A Step-by-Step Guide to Developing Bitcoin Smart Contracts

Design

  • P2PKH is the most popular type of transactions in the bitcoin network used to sending bitcoins from one to another, which is necessary for beginners to understand
  • By implementing this classic transaction type, one can more intuitively understand the capabilities and usage of Script/sCrypt

What’s P2PKH?

OP_DUP OP_HASH160 <Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG
<Signature> <Public Key>

Receiving of P2PKH

Spending of P2PKH

  • The original public key that the above public key hash value is calculated from;
  • A Signature calculated by using the private key corresponding to the original public key.

Verification of P2PKH

  • Concatenate the unlocking script with the locking script to form the following verification Script:
<Signature> <Public Key> OP_DUP OP_HASH160 <Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG
  • Use the Bitcoin Virtual Machine to execute this verification Script to check whether the execution result is valid. There are two critical checks in the verification process:
  1. Verify that the hash, which can be calculate by the public key information provided in the unlocking script, is equal to the hash provided in the locking script. If it passes, the public key is indeed the recipient address of the previous transaction. (It is equivalent to verifying that the receiving address of the previous transfer is Bob’s bank account number)
  2. Verify that the signature provided in the unlocking script matches the public key information. If it passes, it means that Alice does have control over the private key corresponding to this public key.

Development

git clone git@github.com:sCrypt-Inc/boilerplate.git
Contract DemoP2PKH
  • A contract variable pubKeyHash of type Ripemd160, corresponding to the previous P2PKH locking script <Public Key Hash> ;
  • Constructorconstructor, used to initialize the contract variable;
  • A custom public function named unlock which has two parameter with type Sig and PubKey, corresponding to the previous P2PKH unlocking script<Signature> <Public Key>.The implementation logic also corresponds to the P2PKH validation described earlier.

Unit testing

  • First Import sCrypt’s Javascript/Typescript library scrypttest:
const { buildContractClass, bsv } = require('scrypttest');
  • Use the function buildContractClass to get the class object reflected into Javascript of the contract DemoP2PKH:
const DemoP2PKH = buildContractClass(path.join(__dirname, '../../contracts/p2pkh.scrypt'), tx, inputIndex, inputSatoshis)
  • Use arguments (that is, the hex format of the public key hash) to instantiate the contract:
demo = new DemoP2PKH(toHex(pkh))
  • Test the public method of the contract instance and expect it to succeed:
sig = signTx(tx, privateKey, demo.getLockingScript())
expect(demo.unlock(toHex(sig), toHex(publicKey))).to.equal(true);
  • Expect it to fail if the signature cannot be verified because the wrong private key is used:
sig = signTx(tx, privateKey2, demo.getLockingScript())
expect(demo.unlock(toHex(sig), toHex(publicKey))).to.equal(false);

Debug

launch.json
  • program: the contract file for this debug configuration.
  • constructorParams: the contract’s constructor argument list, separated by comma.
  • entryMethod: specifies the public function name to be debugged.
  • entryMethodParams: specify the actual argument list of the public function to be debugged, also separated by comma.
  • txContext: specifies context information about the current transaction at debugging time, where:
  1. txContext.hex: the hex format of the transaction, can be signed or unsigned.
  2. txContext.inputIndex: the input index corresponding to the contract-locked UTXO to be spent.
  3. txContext.inputSatoshis: The amount of bitcoins corresponding to the contract-locked UTXO to be spent, in unit of satoshi.

Deploy and Call the Contract

Preparations

New privKey generated for testnet: cMtFUvwk43MwBoWs15fU15jWmQEk27yJJjEkWotmPjHHRuXU9qGq
With address: moJnB7AND5TW8suRmdHPbY6knpfE1uJ15n
You could fund the address on testnet & use the privKey to complete the test
  1. A private key on the test network is required;
  2. The private key has sufficient balance in the corresponding address for testing.
const privKey = ''

Expected Result

Contract Deployed Successfully! TxId: bc929f1dddc6652896c7c162314e2651fbcd26495bd1ccf9568219e22fea2fb8
Contract Method Called Successfully! TxId: ce2dba497065d33c1e07bf710ad94e9600c6413e053b4abec2bd8562aea3dc20
p2pkh.deployments.js

Contract Deployment

  1. Create a new locking transaction:
const amountInContract = 10000
const deployTx = await createLockingTx(privateKey.toAddress(), amountInContract)
deployTx.outputs[0].setScript(p2pkh.lockingScript)
deployTx.sign(privateKey)
const deployTxId = await sendTx(deployTx)

Contract Call

  1. Create a new unlocking transaction:
const spendAmount = amountInContract / 10
const methodCallTx = createUnlockingTx(deployTxId, amountInContract, p2pkh.lockingScript.toASM(), spendAmount)
const sig = signTx(methodCallTx, privateKey, p2pkh.lockingScript.toASM(), amountInContract)
const unlockingScript = p2pkh.unlock(new Sig(toHex(sig)), new PubKey(toHex(publicKey))).toScript()
methodCallTx.inputs[0].setScript(unlockingScript)
const methodCallTxId = await sendTx(methodCallTx)

Conclusion

--

--

--

sCrypt Inc (https://scrypt.io) is a company with a mission to provide integrated on-chain smart contracting solutions using the original BitCoin Protocol on BSV

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

everPay x Uniswap Liquidity Mining to earn WAR

Curve & Ellipsis Liquidity Providers Incentives

How the blockchain is interfering in fighting fake medical equipment during this crisis?

Final Results for IOST Q1 2020 Contribution Rankings and Rewards

block42 Company Update Q1/2020

Unification Welcomes New Strategic Advisors: Dan Tsui of Kyokan & Allie Zhang of Blocktag

MasterVentures And StackOS Join Forces To Disrupt The Cloud Provider’s Monopoly

block42 contributes to ICON — Update #6

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
sCrypt

sCrypt

sCrypt Inc (https://scrypt.io) is a company with a mission to provide integrated on-chain smart contracting solutions using the original BitCoin Protocol on BSV

More from Medium

Masking and the Use of XOR for Encryption and Decryption

What you Should Know About zk-SNARK

Decentralized Systems in Wars

Bitcoin Transactions