Skip to content

Instantly share code, notes, and snippets.

@mmitech
Forked from dexX7/1_context.md
Last active April 1, 2019 09:12
Show Gist options
  • Save mmitech/92a066b12a2ca03a7739f9cfdfbaebb4 to your computer and use it in GitHub Desktop.
Save mmitech/92a066b12a2ca03a7739f9cfdfbaebb4 to your computer and use it in GitHub Desktop.
Token based 2-of-3 multisig arbitration with Omni Core

Context:

  • Let Alice be the seller of an item or service, and Bob the buyer

  • Trent is a service operator, who has the role of an arbitrator

  • Alice wants to deal in TetherUSD

  • Bob's address is mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH, which is funded with TetherUSD

  • TetherUSD has the token identifier 2147483657

Overview:

  1. Trent (service operator) creates a new key
  2. Trent retrieves the public key of the generated address
  3. Alice (seller) creates a new key
  4. Alice retrieves the public key of the generated address
  5. Bob (buyer) retrieves the public key of mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH
  6. Alice and Bob hand over their public keys to Trent, which creates a multisig address, spendable with at least two of three signatures
  7. Trent retrieves the redeemScript, which is given to Alice and Bob
  8. Bob sends 100.00 TetherUSD to the multisig destination
  9. Trent confirms that the transaction is valid, and notifies Alice to ship the item
  10. Just in case, Alice checks the TetherUSD balance of 2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9, and ships the item
  11. Trent prepares a transaction to pay Alice with 99.00 TetherUSD
  12. Alice confirms she is indeed the recipient of the 99.00 TetherUSD
  13. Alice signs the transaction
  14. Trent confirms that Alice signed the transaction
  15. Bob signs the raw transaction
  16. One of them broadcasts the complete transaction

The chain of RPC calls in detail:

1. Trent (service operator) creates a new key
$ omnicore-cli getnewaddress
mmA4MUEgRNWbtQrMou3S5K8LaEkYDiS14w
2. Trent retrieves the public key of the generated address
$ omnicore-cli validateaddress "mmA4MUEgRNWbtQrMou3S5K8LaEkYDiS14w"
{
    "isvalid" : true,
    "address" : "mmA4MUEgRNWbtQrMou3S5K8LaEkYDiS14w",
    "ismine" : true,
    "iswatchonly" : false,
    "isscript" : false,
    "pubkey" : "0232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff96",
    "iscompressed" : true,
    "account" : ""
}
3. Alice (seller) creates a new key
$ omnicore-cli getnewaddress
moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk
4. Alice retrieves the public key of the generated address
$ omnicore-cli validateaddress "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk"
{
    "isvalid" : true,
    "address" : "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk",
    "ismine" : true,
    "iswatchonly" : false,
    "isscript" : false,
    "pubkey" : "02343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e",
    "iscompressed" : true,
    "account" : ""
}
5. Bob (buyer) retrieves the public key of mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH
$ omnicore-cli validateaddress "mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH"
{
    "isvalid" : true,
    "address" : "mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH",
    "ismine" : true,
    "iswatchonly" : false,
    "isscript" : false,
    "pubkey" : "027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b",
    "iscompressed" : true,
    "account" : ""
}
6. Alice and Bob hand over their public keys to Trent, which creates a multisig address, spendable with at least two of three signatures
$ omnicore-cli addmultisigaddress 2 '["0232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff96","02343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e","027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b"]'
2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9
7. Trent retrieves the redeemScript, which is given to Alice and Bob

Alternatively: createmultisig 2 '["0232..","0234..", "027a.."]'

$ omnicore-cli validateaddress "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9"
{
    "isvalid" : true,
    "address" : "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9",
    "ismine" : true,
    "iswatchonly" : false,
    "isscript" : true,
    "script" : "multisig",
    "hex" : "52210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53ae",
    "addresses" : [
        "mmA4MUEgRNWbtQrMou3S5K8LaEkYDiS14w",
        "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk",
        "mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH"
    ],
    "sigsrequired" : 2,
    "account" : ""
}
8. Bob sends 100.00 TetherUSD to the multisig destination
$ omnicore-cli omni_send "mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH" "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9" 2147483657 "100.00"
2d4de9693432e76a0323e909aceae367cd52caf57f695cc8c463e3d447be4a2f
9. Trent confirms that the transaction is valid, and notifies Alice to ship the item
$ omnicore-cli omni_gettransaction "2d4de9693432e76a0323e909aceae367cd52caf57f695cc8c463e3d447be4a2f"
{
    "txid" : "2d4de9693432e76a0323e909aceae367cd52caf57f695cc8c463e3d447be4a2f",
    "sendingaddress" : "mkXZ1FYBNuvrqMEE2PLzJkS39T6w7CouFH",
    "referenceaddress" : "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9",
    "ismine" : true,
    "fee" : "0.00010000",
    "confirmations" : 1,
    "blocktime" : 1437213966,
    "valid" : true,
    "version" : 0,
    "type_int" : 0,
    "type" : "Simple Send",
    "propertyid" : 2147483657,
    "divisible" : true,
    "amount" : "100.00000000"
}
10. Alice checks the TetherUSD balance of 2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9, and ships the item
$ omnicore-cli omni_getbalance "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9" 2147483657
{
    "balance" : "100.00000000",
    "reserved" : "0.00000000"
}
11. Trent prepares a transaction to pay Alice with 99.00 TetherUSD
  • Issue 1: when, and how is the service fee for Trent subtracted?
  • Issue 2: where are the bitcoins coming from to pay the transaction fee?

to use an utxo use omnicore-cli listunspent to get a list of utxos, We assume someone sent 0.0005 BTC to 2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9 to pay for transaction fees for this example: (

  • txid: 41a76b319ba24cd32fecd85fe234e32aa58c6151d964ca5968b8b41415a906e0
  • vout: 0
  • scriptPubKey: a9148baa686154e24014b546f3cb5223f16c9f4af17f87
$ omnicore-cli omni_createrawsend '[{"txid":"41a76b319ba24cd32fecd85fe234e32aa58c6151d964ca5968b8b41415a906e0","vout":0}]' "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk" 2147483657 "99.00"
0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba7410000000000ffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000
12. Alice confirms she is indeed the recipient of the 99.00 TetherUSD
$ omnicore-cli omni_decodetransaction "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba7410000000000ffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000"
{
    "txid" : "579453d90ec4f5dd9d21a5a357380c1aa933fcf1b0510facc3a352d686aaf1a2",
    "sendingaddress" : "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9",
    "referenceaddress" : "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk",
    "ismine" : true,
    "fee" : "0.00010000",
    "confirmations" : 0,
    "valid" : false,
    "version" : 0,
    "type_int" : 0,
    "type" : "Simple Send",
    "propertyid" : 2147483657,
    "divisible" : true,
    "amount" : "99.00000000"
}
13. Alice signs the transaction

Issue 4: the result isn't intuitive, and the only way to tell, whether a signature was added, is by observing the increased size of the now partially signed raw transaction

$ omnicore-cli signrawtransaction "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba7410000000000ffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000"
{
    "hex" : "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba74100000000b40047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53aeffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000",
    "complete" : false,
    "errors" : [
        {
            "txid" : "41a76b319ba24cd32fecd85fe234e32aa58c6151d964ca5968b8b41415a906e0",
            "vout" : 0,
            "scriptSig" : "0047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53ae",
            "sequence" : 4294967295,
            "error" : "Operation not valid with the current stack size"
        }
    ]
}
14. Trent confirms that Alice signed the transaction

Issue 5: there is no obvious way to determine, who signed the transaction

$ omnicore-cli decoderawtransaction "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba74100000000b40047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53aeffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000"
{
    "txid" : "cca7d30709175568c5f624fadb3c5c1b775318a1fbbab95d07d242dfcc69125d",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "41a76b319ba24cd32fecd85fe234e32aa58c6151d964ca5968b8b41415a906e0",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "0 304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd01 52210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53ae",
                "hex" : "0047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53ae"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 0.00000000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_RETURN 6f6d6e690000000080000009000000024e160300",
                "hex" : "6a146f6d6e690000000080000009000000024e160300",
                "type" : "nulldata"
            }
        },
        {
            "value" : 0.00000546,
            "n" : 1,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 58512eab73b83c9f0d2569c9243bf4df63d43aae OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk"
                ]
            }
        },
        {
            "value" : 0.00039454,
            "n" : 2,
            "scriptPubKey" : {
                "asm" : "OP_HASH160 8baa686154e24014b546f3cb5223f16c9f4af17f OP_EQUAL",
                "hex" : "a9148baa686154e24014b546f3cb5223f16c9f4af17f87",
                "reqSigs" : 1,
                "type" : "scripthash",
                "addresses" : [
                    "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9"
                ]
            }
        }
    ]
}
15. Bob signs the raw transaction

Issue 6: this is the alternative way of signing without using "addmultisig" first, but it is required to provide low level transaction details and explicitly sign with the private key, even if it's in the wallet

$ omnicore-cli signrawtransaction "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba74100000000b40047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53aeffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000" '[{"txid":"41a76b319ba24cd32fecd85fe234e32aa58c6151d964ca5968b8b41415a906e0","vout":0,"scriptPubKey":"a9148baa686154e24014b546f3cb5223f16c9f4af17f87","redeemScript":"52210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53ae"}]' '["cQoN38zUcZV9egX8XbMv5B2CPzaAg4ccdVPGxdwbpdy3TPt85eS8"]'
{
    "hex" : "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba74100000000fdfd000047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014830450221008818a0b632ae010bf01378a54bd0d81d29abf35fd59626c822bc05380b2ec02302201328d86924b1b8ac3fb097301d24d07bbf9ed9d337a1da3425a20e88e3ec3181014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53aeffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000",
    "complete" : true
}
16. One of them broadcasts the complete transaction
$ omnicore-cli sendrawtransaction "0100000001e006a91514b4b86859ca64d951618ca52ae334e25fd8ec2fd34ca29b316ba74100000000fdfd000047304402202875eab5ad8668d38398cc7fd132b0a47ee08831522409082793c8766fcfd684022044b7b33d365089d9a04f73e626bd9887321d839da4f4ac0900365c068bba92cd014830450221008818a0b632ae010bf01378a54bd0d81d29abf35fd59626c822bc05380b2ec02302201328d86924b1b8ac3fb097301d24d07bbf9ed9d337a1da3425a20e88e3ec3181014c6952210232b7c756b51c8ad37fa63929d119b118af54598c8a0f1ab8f1966704e4cbff962102343986778e78ff014076967c5f49923e3304c43c79e58e82f4119df19833ba8e21027aa3757d4a869a8e886a4562322a251fe8a7b1c710a8a33f7aad980c9e6e9a3b53aeffffffff030000000000000000166a146f6d6e690000000080000009000000024e16030022020000000000001976a91458512eab73b83c9f0d2569c9243bf4df63d43aae88ac1e9a00000000000017a9148baa686154e24014b546f3cb5223f16c9f4af17f8700000000"
cffed6126d0adcf9277c345cbb87db0a973a0b6e6b8ce14b15e452f0144f794a
Bonus: after confirmation, check that the broadcasted transaction is really valid
$ omnicore-cli omni_gettransaction "cffed6126d0adcf9277c345cbb87db0a973a0b6e6b8ce14b15e452f0144f794a"
{
    "txid" : "cffed6126d0adcf9277c345cbb87db0a973a0b6e6b8ce14b15e452f0144f794a",
    "sendingaddress" : "2N5yi45uWWpCETvUQqVPQ6y6TtLJtBFtJj9",
    "referenceaddress" : "moZw1acs1CvXihvzcLUt51Z2a7xv1Lq9Rk",
    "ismine" : true,
    "fee" : "0.00010000",
    "confirmations" : 1,
    "blocktime" : 1437221123,
    "valid" : true,
    "version" : 0,
    "type_int" : 0,
    "type" : "Simple Send",
    "propertyid" : 2147483657,
    "divisible" : true,
    "amount" : "99.00000000"
}

Notes:

When using createmultisig or addmultisigaddress, then the order of public keys matters, and has an impact on the resulting redeemScript!

The commands omni_createrawsend and omni_decodetransaction are not yet merged into the main branch of Omni Core.

Usability is very likely the biggest hurdle in the whole scheme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment