Bitcoin contracts
function parseInto(source, editor) {
internals.readTransactionFromHexString(source.get()).then(function(tx) {
editor.set(JSON.stringify(tx, null, 2));
}, function(e) {
editor.set("// parse error: " + e);
});
}
parseInto(source, target);
Bitcoin is designed to support a wide variety of transaction types. Although currently the majority of transactions are standard payments to address it is possible to build more complex protocols.
Block chain can be used to build agreements between people that do not require trust or central authorities. Properties exchanged via the block chain may even be physical things like cars.
Bitcoin achieves high flexibility due to three features:
- scripts — unlocking funds in transactions is done using a simple scripting language,
- signature hash flags — indicate which parts of the transaction are signed,
- sequence numbers and lock time — mark transactions as not valid until specified time.
This implementation uses several ES6 features not yet enabled by default in Chrome (version 36). It is necessary to enable Experimental JavaScript at chrome://flags/#enable-javascript-harmony.
Firefox (version 31) supports generators as well as Promises.
- ES6 generators
- JavaScript Promises
Stack visualization uses Most of Bitcoin transactions are sending funds to an address. Addresses are encoded public key hashes with a checksum. Sending bitcoins to an address internally creates a transaction containing a script with embedded public key hash. This script checks if the spending transaction is signed by a correct key. The address below is a version 1 bitcoin address: Decoding it using the base58 encoding yields a byte array: This array can be split into three parts. First byte is a version tag ( The checksum is verified by using the SHA-256 function on the version and the public key hash twice and taking first four bytes of the digest: The address above is …. The extracted public key hash is used to construct the output script. The script will unlock funds only when the
next transaction provides two parameters — the public key that hashes to the given hash and a signature
created using the private key that matches that public key. Transaction of the left ( Output #0’s script contains the following five operators: The output script can be also represented in a simple programming language as a list of parameters that will be provided by spending the transaction’s input script ( Compiling to the Bitcoin Script results in these opcodes: When a different transaction wants to claim the coins sent to this output it has to provide a second part of the script — the input script. The input script is also called scriptSig as it usually contains signatures. These two scripts — the input script and the output script — are executed in that order and if the execution completes successfully and leaves a truthy item on the top of the stack then the transaction is considered valid. The input script (two opcodes) from the spending transaction is concatenated with the output script from the first one: Stack: Raw bytes of the transaction on the left: Parsed into a JavaScript object reveal the transaction’s structure — Each input references the output in a different transaction (with an exception of inputs in generation transactions), has a sequence number that allows updating that input and a script. Scripts in standard transaction’s inputs push a signature and a public key byte arrays onto the stack. Outputs contain only the Parsed into a JavaScript object: Standard transactions require exactly one key pair to unlock. Using the OP_CHECKMULTISIG operator instead of the OP_CHECKSIG in the output script allows creating transactions that need several keys to unlock funds. A classic example is an escrow where a trusted third party (broker) is used between the merchant and the client to secure funds. A transaction is set up that requires two keys out of three (merchant, client and a trusted party) to move coins. If a good is delivered then the merchant and the client agree to move funds to the merchant’s account. If the merchant fails to send the good, the client and the trusted party move funds back to the client. And if the merchant can prove to the broker that the good was indeed sent then that third party and the merchant send coins to the merchant’s account. Another example of using the OP_CHECKMULTISIG requires both husband and wife agreeing to paying for something or using multiple keys to protect coins in a cold storage. Left transaction’s output #1 contains a script that uses OP_CHECKMULTISIG: The output script represented in a simple programming language: Compiling to the Bitcoin Script results in these opcodes: The input script (three opcodes) from the spending transaction is concatenated with the output script from the first one: Stack: One extra argument ( The first transaction is a lot longer than the standard one because output #1 contains full public keys and not just their hashes. Raw bytes of the transaction on the left: Transaction object: Raw bytes of the transaction on the right: Transaction object: Each signature used in input scripts contains a flags field indicating which parts of the transaction are signed. Using this field it is possible to implement crowdfunding campaign (or any other assurance contract). An entrepreneur announces that they will complete a project only when a specified amount of bitcoins (for example 150 μBTC) is collected. Backers who want to pledge money create transactions sending bitcoins (for example 50 μBTC) to this address, setting the output value to the target amount (150 μBTC) and sign it with These pledge transactions are not broadcast but are sent directly to the entrepreneur. As the output value (150 μBTC) is higher than
the input value (50 μBTC) it is impossible for the entrepreneur to retrieve bitcoins from these transactions directly. The Backers create pledge transactions (on the right) that take a small amount of bitcoins (50 μBTC) and set output to target value (150 μBTC). All pledges have one and the same output containing amount and receiving address of the entrepreneur. Raw bytes of the transaction on the left: Transaction object: Raw bytes of the transaction on the right: Transaction object: When the entrepreneur receives enough funds (the sum of inputs is higher than 150 μBTC) they create the final transaction that takes all inputs from pledges and one output (the same output that is used in all pledges). Because the inputs were signed by backers with the Raw bytes of the final transaction on the right: Transaction object: The following script validates the first input in the final transaction. The only difference between this script and the standard transaction’s is the signature hash type ( Stack: One example that uses both time-locked transactions and non-standard scripts is the decentralized lottery. This scheme allows multiple users to gamble bitcoins so that one of them — randomly — wins. The protocol is composed out of two parts: The example below uses three players that randomly choose a number (0, 1 or 2). If sum of their numbers modulo 3 is 0 the first player wins, if it is 1 the second player wins and if it is 2 the third player wins. To make the lottery secure against brute force attacks players use long strings of random data instead of their random numbers directly. If the drawn number is 0 the player uses a string of length 32, if it is 1 — 33 and if it is 2 — 34. Users create and broadcast transaction that requires either one signature and a secret string or two signatures to unlock. Compiling to Bitcoin Script results in opcodes: The input script (three opcodes) from the spending transaction is concatenated with the output script from the first one: Stack contents: Raw bytes of the transaction on the left: Transaction object: Raw bytes of the reveal transaction on the right: Transaction object: Raw bytes of the fine (pay deposit) transaction on the right: Transaction object: In this phase one of the users creates a transaction that contains hashes of all secrets. The output can be unlocked only when all secrets have been revealed and only by the lottery winner. The output script checks the sizes of revealed secrets and their hashes. Then it computes one number from these sizes and uses it to select a public key that will be used to verify the spending transaction. Compiling to Bitcoin Script results in opcodes: The input script (four opcodes) from the spending transaction is concatenated with the output script from the first one: Stack contents: Raw gamble transaction on the left: Transaction object: Raw spending transaction of the winner: Transaction object: Transactions containing non-standard scripts like these will not be relied through the Bitcoin network but if they are included in a block they will be accepted by the standard client.position: sticky CSS property that can be enabled by Experimental Web Platform Features at chrome://flags/#enable-experimental-web-platform-features in Chrome or layout.css.sticky.enabled toggle at about:config in Firefox.Standard transaction
1DTjvhLV6S72NQrSDrCX1GTCb9B3D5pmCB……), last 4 bytes are used as a checksum (…) and the
rest is a public key hash:……
var hex = internals.hex;
var bytes = internals.base58.decode(address.get());
intro.querySelector('.hex').textContent = hex.encode(bytes);
var checksum = hex.encode(bytes.splice(bytes.length - 4, 4));
intro.querySelector('.version').textContent = hex.encode([bytes[0]]);
intro.querySelector('.checksum').textContent = checksum;
intro.querySelector('.pubkeyhash').textContent = hex.encode(bytes.slice(1));
var sha = hex.encode(digest.sha256(digest.sha256(bytes)));
intro.querySelector('.sha').innerHTML = "<strong>" + sha.substring(0, 8) + "</strong>" + sha.substring(9);
var validity = intro.querySelector('.validity');
validity.textContent = sha.substring(0, 8) === checksum ? "valid" : "invalid";
validity.className = sha.substring(0, 8) === checksum ? "success icon-ok validity" : "failure icon-cancel validity";
082eae) transfers ownership of bitcoins to the address 1DTjvhLV6S72NQrSDrCX1GTCb9B3D5pmCB by setting up a short script in one of its outputs.OP_DUP — duplicates an item on the stack,OP_HASH160 — hashes top-most item on the stack twice — once with SHA-256 and then with RIPEMD-160,88b028348642ad1bbaa8fcc054273070eda045fe — pushes this byte vector onto the stack,OP_EQUALVERIFY — takes two top-most items on the stack and checks if they are equal, if not the entire script execution fails,OP_CHECKSIG — verifies if the current transaction is signed by the correct key (the private key that corresponds to the public key that was hashed earlier).assume statements) and list of assertions that should be met to move funds (verify statements).assume signature, pubKey
verify hash160(pubKey) == '88b028348642ad1bbaa8fcc054273070eda045fe'
verify checkSig(signature, pubKey)
…
var str;
try {
str = superscript.compile(input.get()).join('\n');
} catch (e) {
str = "// Error: " + e;
}
output.textContent = str;
Executing script
// input script
3045022100de14671eaebfe7eaa085e100f40b4a452fdd3a55975a9007062de361dfc4ccb302207a00ee3ec2341a36effa37d0b7b196202348f0840d6b46fa111d040827d1f39b01
0381fa985809e1a23fc261cb4c02ffdc968a1d2548f40428af1931c3e706f5c7d4
// output script
OP_DUP
OP_HASH160
88b028348642ad1bbaa8fcc054273070eda045fe
OP_EQUALVERIFY
OP_CHECKSIGRaw transactions
010000000192572bd6cb7e01247c7f876d63e79e754d7c1e246eda3f2ccf5305b97dc67e73000000006a47304402203a21c63594018be1f0d475ad4cd8e3f6a9465c18ff14ee3da489be8d32690819022019bf6f328c128dcab3cea878cbf2b87efaf4922a0915f8603bef9126eb57ea53012102744bd7d38356ab4563a91b3a2a8aae190feec76cf2e329f488bf429c7b351752ffffffff01b0360000000000001976a91488b028348642ad1bbaa8fcc054273070eda045fe88ac00000000version field that is currently always 1, lockTime that allows creating transactions that will become valid in the future and a list of inputs and outputs.// click Parsevalue in satoshi that is assigned to this output and the output script that will decide whether a different transaction’s input can claim this output’s coins.0100000001c21ae5cfc3a73eba85ad9c7d06304840b1e3f0d147feea41f62ab3392dae2e08000000006b483045022100de14671eaebfe7eaa085e100f40b4a452fdd3a55975a9007062de361dfc4ccb302207a00ee3ec2341a36effa37d0b7b196202348f0840d6b46fa111d040827d1f39b01210381fa985809e1a23fc261cb4c02ffdc968a1d2548f40428af1931c3e706f5c7d4ffffffff01c8320000000000001976a914f4f1d83d4ce7b5a3d2dfb2384af09f6d95c8279388ac00000000// click ParseEscrow
OP_2 — pushes digit 2 on the stack (number of required signatures),041ce544058996033a34adb07be380e63956c588… — pushes first public key,04db5efff14362653c0fc2e5437ac964dd3e0931… — pushes second public key,043b9264a9afb2c9dbc3602cf25ab9a5f5ee1f99… — pushes third public key,OP_3 — pushes digit 3 on the stack (number of provided public keys),OP_CHECKMULTISIG — takes a number of public keys, then these public keys, then a number of signatures and these signatures and performs the signature verification, if all signatures are valid pushes true on the stack, false otherwise.assume unused, signature1, signature2
let pubKeyA = '041ce544058996033a34adb07be380e63956c588dd036d20824447d88700ec91f45a98894bbbdab68ac304b5e68f77ea2f614516d0ace35f76e3b376b9917d6c84'
let pubKeyB = '04db5efff14362653c0fc2e5437ac964dd3e093110c8fbcd5d9fd135ec3c98dc926d26b344def4397c3d99ebbd56e35c53cdd501e2c7a9a0cc5c2b04e7d0a38751'
let pubKeyC = '043b9264a9afb2c9dbc3602cf25ab9a5f5ee1f991e6edfb9c2982a9d31cd7e41c2c9c2a8ad2a8da0c8943b54192c9fea120bf5cce390b459269698efaadb42d649'
verify checkMultiSig(2, pubKeyA, pubKeyB, pubKeyC, 3)…Executing script
// input script
OP_FALSE
30450220523b47504644354214e847d3a91337516835591e25b5eaeefb8c349823c5ff92022100e4fc44e18a252c853495923f0f88668f1aa539f5c69418dfb392d77cff84049c01
3046022100ab63540868657b7674a77c1fc691f6842d8d15f825241d7ad12fb1ff87e63de3022100dec537d994abccebac546bc260f0dbbed6135c7d470f35409a21d21746380fe601
// output script
OP_2
041ce544058996033a34adb07be380e63956c588dd036d20824447d88700ec91f45a98894bbbdab68ac304b5e68f77ea2f614516d0ace35f76e3b376b9917d6c84
04db5efff14362653c0fc2e5437ac964dd3e093110c8fbcd5d9fd135ec3c98dc926d26b344def4397c3d99ebbd56e35c53cdd501e2c7a9a0cc5c2b04e7d0a38751
043b9264a9afb2c9dbc3602cf25ab9a5f5ee1f991e6edfb9c2982a9d31cd7e41c2c9c2a8ad2a8da0c8943b54192c9fea120bf5cce390b459269698efaadb42d649
OP_3
OP_CHECKMULTISIGOP_FALSE) is needed in the input script due to a bug in OP_CHECKMULTISIG.Raw transactions
0100000001c532b97ded19882906d4f8cfb2f5df927010e57cc17816f44a76d28a5b22d650000000008c493046022100fb0c6b6ab08420425e054e4bbc7d2f022229619ad94dcfe6a5091c43b11b8dff02210097ea263ca74fd561470e1e7da37708faa19661963fc388644c83dbb7914aca8601410413a73711ae2ff667b1b4bf60c5cdf1f63f972cbc7c5fbadc50dc5510dc9d25930c2536b6432c8ab8d8ddadb55a96e5ad957fd2f835bc9b6949a86efa3a65d3acffffffff0290d00300000000001976a9148dc294df289c81d6eb61f72475061ee4da2ee5f988ac7082030000000000c95241041ce544058996033a34adb07be380e63956c588dd036d20824447d88700ec91f45a98894bbbdab68ac304b5e68f77ea2f614516d0ace35f76e3b376b9917d6c844104db5efff14362653c0fc2e5437ac964dd3e093110c8fbcd5d9fd135ec3c98dc926d26b344def4397c3d99ebbd56e35c53cdd501e2c7a9a0cc5c2b04e7d0a3875141043b9264a9afb2c9dbc3602cf25ab9a5f5ee1f991e6edfb9c2982a9d31cd7e41c2c9c2a8ad2a8da0c8943b54192c9fea120bf5cce390b459269698efaadb42d64953ae00000000// click Parse0100000001c68db8fc6652dc9d7c7a58e48c118c42086f670dd8f87987625cc910ef9cfd4b0100000094004830450220523b47504644354214e847d3a91337516835591e25b5eaeefb8c349823c5ff92022100e4fc44e18a252c853495923f0f88668f1aa539f5c69418dfb392d77cff84049c01493046022100ab63540868657b7674a77c1fc691f6842d8d15f825241d7ad12fb1ff87e63de3022100dec537d994abccebac546bc260f0dbbed6135c7d470f35409a21d21746380fe601ffffffff01605b0300000000001976a9149bfdf3e906ce07448dac85ce385ab6bdad7e7b8188ac00000000// click ParseKickstarter
SIGHASH_ANYONECANPAY flag.SIGHASH_ANYONECANPAY flag allows merging transaction inputs. When enough funds have been gathered (the sum of inputs is higher than target value) the entrepreneur creates one final transaction from all pledges and broadcasts it collecting all the funds.Creating pledges
Raw transaction
01000000011f5e7131923054920104e5080983572c6e29366d0c7f95548398e7a1c80dfa23500000006b4830450221009ce31d9d621c4ef2a753cb238d8bbb4b02edaf17cea98d95945011b84448bd39022010c699f51a8d1399748ce57b3db3ccd7a076872fd564492df96b1c7ff5ad57e5012103a72a9fc1615f45b461534c0a035ea4ea228f86c11f52dbfa6997f1483dbcc21bffffffff0188130000000000001976a914da8df9cc99e719562b52c209ebea7e28b8b3c60b88ac00000000// click ParseRaw transaction — pledge
0100000001b6c88c761235e7ccc6ee59d53348537c94a4fe1adaf04c92ce767b4f4c078d87000000006a4730440220207ab184b288275c6466075d724a9f632487b6996489d49c8148cf30f9d5fc1a0220518b62471a25f8da86d0184de5b0496d4c2b272115c84fa58ea32e568b53053d8121032153889b1813175f337f24944ff632a6b9a78b63e09ff8c6a569f5d5d429cf97ffffffff01983a0000000000001976a91454000657e2b8ebed5b1a1565b17aec63583ddc6688ac00000000// click ParseCollecting funds
SIGHASH_ANYONECANPAY flag the signatures are still valid. The final transaction is broadcast and the entrepreneur collects all the pledges.Raw final transaction
0100000004b6c88c761235e7ccc6ee59d53348537c94a4fe1adaf04c92ce767b4f4c078d87000000006a4730440220207ab184b288275c6466075d724a9f632487b6996489d49c8148cf30f9d5fc1a0220518b62471a25f8da86d0184de5b0496d4c2b272115c84fa58ea32e568b53053d8121032153889b1813175f337f24944ff632a6b9a78b63e09ff8c6a569f5d5d429cf97ffffffff064a3e45ad865f6ee493e0d1dc48d54f8f275ddf5f9f271cae1d294d70e43d44000000006b483045022059f303e73e34d3e56bc6a91ee02248da2ff12ffcdf8b676bc743f886c90ef165022100a4d7e00e4d325fe7e7406757bc9647e2f4f620ceb30ce759e22ecb88fc67f8b081210341607135b7e955eacd6d14018348911c5fc7b930af359ee9ced887f175ba89c4fffffffff0f231fc2ac7fdc5a62836127a747b795931f65a9a4b7379448521617b6c6286000000006a473044022001e345ebcc3e8c0673a77dd9e5fa2bf3d0fa295c7eb867edd4e9269b5bd4e8d002200970be9d82380a4cb7b7778fe078992b65199a5f77e07f953119f44ced6e7a5a8121033a76c02081da7453bc040f781959cca920f19cc2344731510bd81cde3469febfffffffff84639d836b4c7558f815a53fbcaed239f5383dec4e4d6a61c79cd0ff8adf92f3000000006b48304502200a513923f5e71f9f84377a605d38ecb7978d3ea013a58e60bce77ac1c8b94bc5022100d1b9547e610ce4022877dc95ab7cbd9538679a7ecd04f7da300270871b53256e81210341607135b7e955eacd6d14018348911c5fc7b930af359ee9ced887f175ba89c4ffffffff01983a0000000000001976a91454000657e2b8ebed5b1a1565b17aec63583ddc6688ac00000000// click ParseExecuting script
81 — ALL with ANYONECANPAY flag) at the end of the backer’s signature (line 2). Standard transactions are signed with ALL (01).// input script
30440220207ab184b288275c6466075d724a9f632487b6996489d49c8148cf30f9d5fc1a0220518b62471a25f8da86d0184de5b0496d4c2b272115c84fa58ea32e568b53053d81
032153889b1813175f337f24944ff632a6b9a78b63e09ff8c6a569f5d5d429cf97
// output script
OP_DUP
OP_HASH160
da8df9cc99e719562b52c209ebea7e28b8b3c60b
OP_EQUALVERIFY
OP_CHECKSIGMultilottery
Open phase
assume signatureA, signatureB, secret
let secretKnown = sha256(secret) == '527ccdd755dcccf03192383624e0a7d0263815ce2ecf1f69cb0423ab7e6f0f3e'
let pubKeyA = '04d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc691'
let pubKeyB = '04c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40d'
let signedByA = checkSig(signatureA, pubKeyA)
let signedByB = checkSig(signatureB, pubKeyB)
verify (secretKnown || signedByB) && signedByA…Open phase — Executing reveal script
// input script
30440220749de3ac2a014374ca7952ebbbd5e094ed45c90f1d069d392c2c0589e3812e330220261f1d1184a4d1b4b4424d710a19dcff492404e1831a6ef8e251000b7f8de95d01
30450220363ee61c89c8369df409c186f099c60e128b758e64364100011c39df91141c3b022100ab26b4a7c2bbd3c14ef30d71d063c8a0db61a20e4dd856fbffe60ca26ea0f15e01
ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568123
// output script
OP_SHA256
527ccdd755dcccf03192383624e0a7d0263815ce2ecf1f69cb0423ab7e6f0f3e
OP_EQUAL
OP_SWAP
04d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc691
OP_CHECKSIG
OP_BOOLOR
OP_SWAP
04c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40d
OP_CHECKSIG
OP_BOOLANDOpen phase — raw transactions
01000000012c67b1b6feba79d0bfa5449fa28df67561a7f24e510efacf6942d0507e3baf33010000008c493046022100a2d5a7577529f4ce88e0a6a109b56a825c9131f0f3f692335f717b95f9e04370022100e753f58b46f9668c75441df19063b4aed358e2125b505c26681987f0505fd492014104c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40dffffffff01a086010000000000ada820527ccdd755dcccf03192383624e0a7d0263815ce2ecf1f69cb0423ab7e6f0f3e877c4104d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc691ac9b7c4104c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40dac9a00000000// click Parse010000000131aee0997b9f607efb0a69cd50ad3e74e28686184f914aa55b5a10f20a76e57a00000000b24730440220749de3ac2a014374ca7952ebbbd5e094ed45c90f1d069d392c2c0589e3812e330220261f1d1184a4d1b4b4424d710a19dcff492404e1831a6ef8e251000b7f8de95d014830450220363ee61c89c8369df409c186f099c60e128b758e64364100011c39df91141c3b022100ab26b4a7c2bbd3c14ef30d71d063c8a0db61a20e4dd856fbffe60ca26ea0f15e0120ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568123ffffffff01905f0100000000001976a914ed8600720a03985c1816b24d6b1622d0ed58861a88ac00000000// click Parse010000000131aee0997b9f607efb0a69cd50ad3e74e28686184f914aa55b5a10f20a76e57a0000000095483045022100a27c9532f4eb90240f598aa4c3ad43bc604fb4464688dad8113a943212d6638f022035ff6f215a4a432590d987f9c8ea839678506904a97643e8e99371b991b9438001493046022100b9d333b096a2a19bf6aa142aa429e7feb4d400b7af82bed4f5eca3ea7b7e83ec02210082d5be5da0a523c9c6e86ecf48f16cfbe3b32def49c92ce376cc87aa746760860101000000000001c8af0000000000001976a91462a2486468040e8a1a1f91d8949ac4dc838a0ed288ac4e258552// click ParseGamble phase
assume signature, sC, sB, sA
let sizeA = size(sA)
verify within(sizeA, 32, 35)
verify sha256(sA) == '197bf68fb520e8d3419dc1d4ac1eb89e7dfd7cfe561c19abf7611d7626d9f02c'
let sizeB = size(sB)
verify within(sizeB, 32, 35)
verify sha256(sB) == 'f531f3041d3136701ea09067c53e7159c8f9b2746a56c3d82966c54bbc553226'
let sizeC = size(sC)
verify within(sizeC, 32, 35)
verify sha256(sC) == '527ccdd755dcccf03192383624e0a7d0263815ce2ecf1f69cb0423ab7e6f0f3e'
// sum of random numbers modulo 3
let mutable num = sizeB + sizeC + sizeA - 96
if (num > 2) {
num <- num - 3
}
if (num > 2) {
num <- num - 3
}
let keyA = '04d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc691'
let keyB = '04208a50909284aede02ad107bb1f52175b025cdf0453537b686433bcade6d3e210b6c82bcbdf8676b2161687e232f5d9afdaa4ed7b3e3bf9608d41b40ebde6ed4'
let keyC = '04c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40d'
// select one of keys using num (if num == 0 -> keyA etc.)
let key = roll(keyA, keyB, keyC, num)
verify checkSigVerify(signature, key)…Gamble phase — Executing winner’s script
// input script
304402207d9184b4e4a1fe11bcb7743db85f1f82ff00ab8c54f58b44de2ae50d8b1c35f3022019d9f60cd927a317e258d7ee3b9ceba49cd2a6bf15c195e4fc5d5f5915b83b6201
ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568123
1b1b01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c227f
2c2c01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c338e
// output script
OP_SIZE
OP_TUCK
20
23
OP_WITHIN
OP_VERIFY
OP_SHA256
197bf68fb520e8d3419dc1d4ac1eb89e7dfd7cfe561c19abf7611d7626d9f02c
OP_EQUALVERIFY
OP_SWAP
OP_SIZE
OP_TUCK
20
23
OP_WITHIN
OP_VERIFY
OP_SHA256
f531f3041d3136701ea09067c53e7159c8f9b2746a56c3d82966c54bbc553226
OP_EQUALVERIFY
OP_ROT
OP_SIZE
OP_TUCK
20
23
OP_WITHIN
OP_VERIFY
OP_SHA256
527ccdd755dcccf03192383624e0a7d0263815ce2ecf1f69cb0423ab7e6f0f3e
OP_EQUALVERIFY
OP_ADD
OP_ADD
60
OP_SUB
OP_DUP
OP_2
OP_GREATERTHAN
OP_IF
OP_3
OP_SUB
OP_ENDIF
OP_DUP
OP_2
OP_GREATERTHAN
OP_IF
OP_3
OP_SUB
OP_ENDIF
04d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc691
04208a50909284aede02ad107bb1f52175b025cdf0453537b686433bcade6d3e210b6c82bcbdf8676b2161687e232f5d9afdaa4ed7b3e3bf9608d41b40ebde6ed4
04c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40d
OP_3
OP_ROLL
OP_ROLL
OP_3
OP_ROLL
OP_SWAP
OP_CHECKSIGVERIFYGamble phase — raw transactions
010000000397341cb62ff241b4a86063751885a072f4a6abe08e0fbe4548dc4c19fb5f1b190100000089463043021f174f4f000f1d4f4b62dde3659b2ae4563c894433319c3e4371b3a2cc0751cf022054890080a18f858a37254ad3ea913213377b459e58c467aaf1432d06a047800c014104d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc691ffffffffa5e8e5f4701195ce07d6319e2eea5bdf422019d1672eeb11f7c97a92821259ed010000008c493046022100f69891463fc2d1a714fbb8761410a0ce2df3f5dc5d24ed232ef1e14fb3476f08022100cada2c329383e11e9c6358d0215643f3ce9dbb267ec263d74569a4dc1df4ae42014104208a50909284aede02ad107bb1f52175b025cdf0453537b686433bcade6d3e210b6c82bcbdf8676b2161687e232f5d9afdaa4ed7b3e3bf9608d41b40ebde6ed4ffffffffd60c2dbd9907a8acb28f83ff0ebc6731c6f9d0917d9bd87f0d5cae8fcb273d72000000008b48304502200c3623da2de1c02910293a70428862d73c32ca8cffbe3e421b54348e8584317d022100b9b19f3de332c9464d99f23e88b0a5ce9e643e23254bbb197edd7fefc6992b56014104c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40dffffffff013057050000000000fd6301827d01200123a569a820197bf68fb520e8d3419dc1d4ac1eb89e7dfd7cfe561c19abf7611d7626d9f02c887c827d01200123a569a820f531f3041d3136701ea09067c53e7159c8f9b2746a56c3d82966c54bbc553226887b827d01200123a569a820527ccdd755dcccf03192383624e0a7d0263815ce2ecf1f69cb0423ab7e6f0f3e8893930160947652a0635394687652a0635394684104d4bf4642f56fc7af0d2382e2cac34fa16ed3321633f91d06128f0e5c0d17479778cc1f2cc7e4a0c6f1e72d905532e8e127a031bb9794b3ef9b68b657f51cc6914104208a50909284aede02ad107bb1f52175b025cdf0453537b686433bcade6d3e210b6c82bcbdf8676b2161687e232f5d9afdaa4ed7b3e3bf9608d41b40ebde6ed44104c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40d537a7a537a7cad00000000// click Parse0100000001a48a2cf33ecd5134784418646820bd69d6c1ceff36dd5497200073d56b810d5400000000ab47304402207d9184b4e4a1fe11bcb7743db85f1f82ff00ab8c54f58b44de2ae50d8b1c35f3022019d9f60cd927a317e258d7ee3b9ceba49cd2a6bf15c195e4fc5d5f5915b83b620120ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568123201b1b01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c227f202c2c01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c338effffffff012030050000000000434104c9ce67ff2df2cd6be5f58345b4e311c5f10aab49d3cf3f73e8dcac1f9cd0de966e924be091e7bc854aef0d0baafa80fe5f2d6af56b1788e1e8ec8d241b41c40dac00000000// click Parse
Comments
Revisions
- Initial version.