Skip to content

Instantly share code, notes, and snippets.

@phm87
Last active October 13, 2020 02:01
Show Gist options
  • Save phm87/64f2ba7aa7393cbd80cc9dd99db8d797 to your computer and use it in GitHub Desktop.
Save phm87/64f2ba7aa7393cbd80cc9dd99db8d797 to your computer and use it in GitHub Desktop.
Tokenize testnet bitcoins on a komodo assetchain/smartchain
**btc_on_ac** is tokenizing testnet bitcoins on a komodo assetchain/smartchain.
An address is a human-readable encoding (with a network prefix) of a pubkey. A private key that controls coins on one address is also controlling coins on all addresses that are built on the same pubkey with any network prefix. In the following explanation, I'll consider that a BTC address is the same as a KMD/smartchain address (because it is the same pubkey).
Multisigs are used as n-of-m such as 7 of 12 signers to have some redundancy.
# How does it work ?
btc_on_ac is based on several public testnet Bitcoin explorer (with API) and a deposit bitcoin/komodo address (pubkey) hardcoded in the code.
For each block mined,
- if no testnet bitcoins were sent to the deposit address, block reward is 0.
- if some testnet bitcoins were sent to the deposit address, block reward is equal to the number of bitcoins sent and this block reward is mined on the KMD sender's address.
In the **first implementation**, the deposit address is a burnt address (or an address controlled by the team) so BTC can be converted to smartchain coins but smartchain coins can't be converted to testnet bitcoins.
Risks:
- if a malicious mining pool is trying to mine a block without a bitcoin transaction, the block should be rejected by network,
- if a malicious actor is running 60 000 fake nodes to have its malicious block accepted, the attack can be mitigated if there are at least 2 honest nodes.
- Risk of attack on testnet Bitcoin explorers (or man-in-the-middle attack)
In a **second implementation**, the deposit address is a multisig address controlled by a know set of notaries. These notaries are trusted entities so this will add some centralisation.
For each block mined,
- if no testnet bitcoins were sent to the deposit address, block reward is 0.
- if some testnet bitcoins were sent to the deposit address, block reward is equal to the number of bitcoins sent and this block reward is mined on the KMD sender's address.
- if no assetchains coins were sent to the deposit address, no bitcoins are unlocked.
- if some assetchains coins were sent to the deposit address, a bitcoin tx is crafted and signed (by the set of notaries) to unlock/redeem some bitcoins sent back to the BTC address that sent the smartchains coins.
Additonal Risks:
- Risk of collusion of notaries to steal testnet bitcoins
- Legal risk since notaries controls funds of other entities without KYC/ALM
In a **third implementation**, the depositor's address is used in the multisig. Then a unique multisig is created for each new depositor.
Using a P2SH instead of a multisig could allow to maker depositor's signature mandatory to unlock/redeem the testnet bitcoins.
This will reduces risks of the first implementation.
In an **alternate implementation**, a bitcoin local node could be used instead of testnet Bitcoin explorers APIs.
This will reduce exposure to risks of attacks on testnet Bitcoin explorers.
# Tech details
## testnet Bitcoin explorers with API
https://api.blockcypher.com/v1/btc/test3/addrs/tb1qh8xp0nalrh3ynnwhcp6lf6kv92kstgwm3pauwx?limit=2
https://www.blockcypher.com/dev/bitcoin/#restful-resources
## multisig
```address1=$(bitcoin-cli getnewaddress)
pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r '.pubkey')
bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]'''
{
"address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr",
"redeemScript": "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae",
"descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y"
}
utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid')
utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout')
recipient="2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr"
rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.000065}''')
signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex')
bitcoin-cli -named sendrawtransaction hexstring=$signedtx```
Source: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_1_Sending_a_Transaction_to_a_Multisig.md
Spending:
```bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz rescan="false"
utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521
utxo_vout=0
utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387
redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae"
rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''')
bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"]' | jq -r '. | .hex'
bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]'
{
"hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000d90047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e301473044022000a402ec4549a65799688dd531d7b18b03c6379416cc8c29b92011987084e9f402205470e24781509c70e2410aaa6d827aa133d6df2c578e96a496b885584fb039200147522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000",
"complete": true
}
signedtx=$(bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' | jq -r .hex)
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx```
Source: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_2_Spending_a_Transaction_to_a_Multisig.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment