Use sCrypt to implement Token atomic swap smart contract

Atomic exchange refers to the trustless exchange between different assets without counterparty risk (that is, one party defaults and the other party loses assets). Next, we will show a general method, using the sCrypt language to implement an atomic exchange smart contract between Bitcoin and token.

Token sale contract

We will develop a token sale contract for transactions between Bitcoin and the 1st layer token 1 on the Bitcoin network. This contract will not present the risk of one party defaulting. Anyone can send bitcoins to the contract to purchase tokens and guarantee to automatically obtain the number of tokens calculated at the predetermined price. The contract is enforced at the consensus level, verified and recorded by miners on the chain. The contract is based on two Bitcoin smart contract technologies, stateful smart contracts and 1-layer tokens . The complete contract code is as follows:

import "util.scrypt";

/**
* A toy token sale
*/
contract TokenSale {
    
    
    // satoshis / token
    int price;

	constructor(int price) {
    
    
		this.price = price;
	}

    public function buy(PubKey buyer, int numTokens, bytes txPreimage) {
    
    
        // this ensures the preimage is for the current tx
        require(Tx.checkPreimage(txPreimage));

        // read previous locking script
        bytes lockingScript = Util.scriptCode(txPreimage);
        int scriptLen = length(lockingScript);
        int oldBalance = Util.value(txPreimage);
        int newBalance = oldBalance + numTokens * this.price;

        // write new locking script
        bytes lockingScript_ = lockingScript + b'22' /* "OP_PUSHDATA0" */ + buyer + num2bin(numTokens, 1);
        bytes hashOutputs = Util.hashOutputs(txPreimage);
        Sha256 hashOutputs_ = hash256(num2bin(newBalance, 8) + Util.writeVarint(lockingScript_));
        require(hashOutputs == hashOutputs_);
    }
}

As in the previous article, the following line of code ensures that the preimage comes from the current transaction:

require(Tx.checkPreimage(txPreimage));

Read the balance in the previous contract, that is, the number of bitcoins in the output of the previous transaction spent by the current input:

int oldBalance = Util.value(txPreimage);

Calculate the bitcoin balance of the new contract:

int newBalance = oldBalance + numTokens * this.price;

Update the number of tokens held by the buyer (that is, update the contract status) and place it in the data part of the contract:

bytes lockingScript_ = lockingScript + b'22' /* "OP_PUSHDATA0" */ + buyer + num2bin(numTokens, 1);

The remaining code verifies that the new bitcoin balance and token allocation table are consistent with those in the new output:

bytes hashOutputs = Util.hashOutputs(txPreimage);
Sha256 hashOutputs_ = hash256(num2bin(newBalance, 8) + Util.writeVarint(lockingScript_));
require(hashOutputs == hashOutputs_);

Here is some sample code using this contract .

Expand

We just demonstrated the basic principles of atomic swaps. There are many ways to extend it to make it more practical and powerful. Here are some examples:

  • Exchange Bitcoin and 2-layer token 2 ; exchange 1-layer token and 2-layer token.
  • Add another public method to allow the issuer to redeem the funds in the contract.
  • The time (ie nLocktime) is obtained through the technology in the contract CheckLockTimeVerify , and the function of adjusting the token price according to the time of purchase is realized, and the token circulation time can also be set.
  • If a buyer purchases multiple times, the token distribution records can be merged.

Bill of BitShizzle has improved the basic TokenSale contract and demonstrated it on the Bitcoin SV mainnet . At the price of 1,000 satoshis per token, 5 consecutive purchases were made: 1 token , 3 tokens , 5 tokens , 7 tokens , and 9 tokens . In the end, the contract was paid 25,000 Satoshi, and the token allocation table was updated correctly. The contents of the table are as follows:

tokenSale

advantage

There are several notable differences between this scheme and other existing atomic swap schemes:

  • No interaction is required. There is no need for multiple parties to communicate or cooperate back and forth, so that various problems caused by a non-responsive party can be completely avoided.
  • No time lock is required. Therefore, funds will not be locked.

One exchange is only included in one transaction of the calling contract. Either the transaction is accepted and the bitcoin and token are exchanged immediately; or the transaction is rejected and no exchange will occur. This is a true atomic exchange because there is no intermediate state in the transaction.

appendix


  1. Layer 1 token: refers to the general term for a type of Token smart contract that is implemented using Bitcoin scripts and verified and executed by network miners; ↩︎

  2. 2-layer token: refers to the general term of a type of Token smart contract whose core logic is not verified and executed by network miners; ↩︎

Guess you like

Origin blog.csdn.net/freedomhero/article/details/107321523