NFT environment deployment - vnt.js

This is just an example of contract deployment and calling using vnt.js. For more vnt.js interfaces, please refer to:

premise

1. Operating environment

Installation required

node: v8.11.2

2. Initialize the deployment directory

mkdir deploy
cd deploy
npm init  # This step will generate package.json

3. Installation dependency

Install vnt.js: 0.20.7 and vnt-kit.js 1.0.0

npm install --save https://github.com/vntchain/vnt.js.git
npm install --save https://github.com/vntchain/vnt-kit.js.git

If the installation fails because the g + + package is missing, please install.

Centos: sudo Yum install gcc-c++

Please check other operating systems.

Install other dependencies

# These dependencies are that Ethereum has js tool libraries, and vntchain can be compatible with these tool libraries
npm install --save ethereumjs-tx@1.3.7
npm install --save ethereumjs-account

usage method

1. If you have a vntchain node

If you set up your own vntchain node by running go VNT, and your vntchain node joins the blockchain network. Then, you can use your node for account management, and use some relatively friendly vnt.js interfaces during development to reduce the amount of JS code development
But one thing to note: don't open your vntchain node to the public network, otherwise hackers may use your unlocked private key to steal

Step 1: import vnt.js Library

var Vnt = require("vnt")

Step 2: create vnt provider connection

var vnt = new Vnt();
vnt.setProvider(new vnt.providers.HttpProvider("http://192.168.0.110:8805"));

Step 3: prepare the account to be used and open the account

1. Put the account keystore file to be used into the keystore subdirectory under the vntchain node data directory

2. Declare and open the corresponding account in the code

// Declare account address and password
var from1 = "0x122369f04f32269598789998de33e3d56e2c507a"
var pass1 = ""
var from2 = "0x3dcf0b3787c31b2bdf62d5bc9128a79c2bb18829"
var pass2 = ""
var toAddr = "0x3ea7a559e44e8cabc362ca28b6211611467c76f3"

// Open the account. After opening, the account key will be managed by the vntchain node and used as a transaction signature
vnt.personal.unlockAccount(from1, pass1)
vnt.personal.unlockAccount(from2, pass2)

Step 4: prepare contract code

Read code and abi from file system

var fs = require("fs")  // This is the fs library used. Please introduce it at the beginning of the code

//Define code path
var codeFile = "/home/mycode/erc20/erc20.compress"
//Define abi path
var abiFile = "/home/mycode/erc20/abi.json"
//Reading abi data
var wasmabi = fs.readFileSync(abiFile)
//Parsing abi data into json structure
var abi = JSON.parse(wasmabi.toString("utf-8"))

Step 5: contract creation

//This is the contract creation main function
function deployWasmContract() {
    // Initialize a contract object with abi and load the code file
    var contract = vnt.core.contract(abi).codeFile(codeFile)

    // Deployment contract
    // We don't need explicit signature here. The vntchain node will sign for us. We can deploy the contract by using an encapsulated friendly new interface
    var contractReturned = contract.new(1000000000, "bitcoin", "BTC", {
        from: from1,  //The account corresponding to the from parameter will be used as the transaction signature
        data: contract.code, //Pass in the contract code as data
        gas: 4000000
    }, function(err, myContract){
       if(!err) {
          if(!myContract.address) {
              console.log("transactionHash: ", myContract.transactionHash)
          } else {
              console.log("contract address: ", myContract.address)
          }
       }
     });
}

Step 6: contract call

Give two examples

No actual transaction

In this case, only some queries will be performed, and the status of the chain will not be changed. For example, query the token balance of an account

function GetAmount(address) {
    console.log("get ammount of address: ", address)
    // Generate contract instance
    var contract = vnt.core.contract(abi).at(contractAddr)
    // Call the GetAmount method of the contract. Note that call is used
    r = contract.GetAmount.call(address, {from: from1})
    console.log("result", r.toString())
}

Actual transactions

function Transfer(from, to, amount) {
    // Generate contract instance
    var contract = vnt.core.contract(abi).at(contractAddr)

    // Call the transfer method of the contract to transfer. Note that sendTransaction is used
    contract.transfer.sendTransaction(
    to,amount,{from: from}, function(err, txid) {
        if(err) {
            console.log("error happend: ", err)
        } else {
            getTransactionReceipt(txid, function(receipt) {
                console.log("status: ", receipt.status)
                GetAmount(to)
            })
        }
    })
}

Obtain transaction details according to txid

vnt.js sends transactions asynchronously. After sending transactions, it will directly return txid instead of waiting for the completion of transaction execution. Therefore, we need to write a method ourselves to wait for the completion of transactions:

// This method will query tx information every second until a result is returned, and will call the callback function
function getTransactionReceipt(tx, cb) {
  var receipt = vnt.core.getTransactionReceipt(tx)
  if(!receipt) {
      setTimeout(function () {
          getTransactionReceipt(tx, cb)
      }, 1000);
  } else {
      cb(receipt)
  }
}

2. If you do not have a vntchain node

If you do not have your own vntchain node, but develop by connecting to a node on the public network, you need to manage your own account, generate your own transaction body and sign it.

Step 1: import vnt.js library and ethereumjs TX library

var Vnt = require("vnt")
var vntkit = require("vnt-kit")
var Tx = require("ethereumjs-tx")

Step 2: create vnt provider connection

var vnt = new Vnt();
vnt.setProvider(new vnt.providers.HttpProvider("http://192.168.0.110:8805"));

Step 3: prepare the account to be used and open the account

Load the keystore and decrypt it to obtain the account private key

var ksDir = "/Users/yanfengxi/go/src/github.com/vntchain/vnt_test/ks/"
var kFile1 = "UTC--2018-05-21T03-11-21.232362508Z--122369f04f32269598789998de33e3d56e2c507a"
var pass1 = ""
var kFile2 = "UTC--2018-05-21T03-11-29.472506793Z--3dcf0b3787c31b2bdf62d5bc9128a79c2bb18829"
var pass2 = ""

function openAccount(file, passwd) {
    var content = fs.readFileSync(file).toString("utf-8")
    return vntkit.account.decrypt(content, passwd, false)
}

var account1 = openAccount(ksDir + kFile1, pass1)
var account2 = openAccount(ksDir + kFile2, pass2)

Step 4: prepare contract code

Read code and abi from file system

var fs = require("fs")  // This is the fs library used. Please introduce it at the beginning of the code

//Define code path
var codeFile = "/home/mycode/erc20/erc20.compress"
//Define abi path
var abiFile = "/home/mycode/erc20/abi.json"
//Reading abi data
var wasmabi = fs.readFileSync(abiFile)
//Parsing abi data into json structure
var abi = JSON.parse(wasmabi.toString("utf-8"))

Step 5: contract creation

//This is the contract creation main function
function deployWasmContract() {
    // Contract initialization through abi and code path
    var contract = vnt.core.contract(abi).codeFile(codeFile)

    // Generate contract creation data
    var data = contract.packContructorData(1000000000, "bitcoin", "BTC")

    // Estimate a gas value
    var gas = vnt.core.estimateGas({data: data});

    // Get the next nonce value of account 1
    var nonce = vnt.core.getTransactionCount(account1.address);

    // Generate the transaction structure, and specify fields such as nonce, gaspierce, gaslimit, value, data, etc
    var options = {
       nonce: vnt.toHex(nonce),
       gasPrice: vnt.toHex(30000000000000),
       gasLimit: vnt.toHex(gas),
       value: '0x00',
       data: data,
       chainId: 1  //chainId must be specified here, that is, the chainId of the node you are connected to, otherwise the transaction signature will make an error
    }

    // Generate transaction
    var tx = new Tx(options);
    // Use the prepared private key to sign the transaction
    tx.sign(new Buffer(account1.privateKey.substring(2,), "hex"));

    // Serialize transaction data
    var serializedTx = tx.serialize();

    // Send transaction
    vnt.core.sendRawTransaction('0x' + serializedTx.toString('hex'),
    function(err, txHash) {
      if (err) {
          console.log("err happened: ", err)
      } else {
          // Print hash of transaction
          console.log("transaction hash: ", txHash);
          // Get list of transactions
          getTransactionReceipt(txHash, function(receipt) {
              console.log("tx receipt: ", receipt)
              console.log("tx status: ", receipt.status)
              console.log("contract address: ", receipt.contractAddress)
          })
      }
    });
}

Step 6: contract call

Give two examples

No actual transaction

In this case, only some queries will be performed, and the status of the chain will not be changed. For example, query the token balance of an account

function GetAmount(address) {
    console.log("get ammount of address: ", address)
    // Generate contract instance through abi
    var contract = vnt.core.contract(abi)

    var data = contract.packFunctionData("GetAmount", [address]);

    console.log("the data is: ", data)
    // Get the next nonce value of account 1
    var nonce = vnt.core.getTransactionCount(account1.address);

    // Generate transaction structure, specify to, data and other fields
    var options = {
       to: contractAddr,    // This field is the contract address
       data: data           // This field is the data called by the contract
    }

    // Use the vnt.core.call method to query, and no transaction will be initiated
    var result = vnt.core.call(options)

    // Decode the result and get the result.
    console.log(contract.unPackOutput("GetAmount", result).toString())
}

Actual transactions

function Transfer(from, to, amount) {
    // Using abi to generate contract instances
    var contract = vnt.core.contract(abi)

    // Generate the data used by the contract call. This data is to package the signature and parameters of the transfer method
    var data = contract.packFunctionData("transfer", [to, amount]);

    // Gets the next nonce value
    var nonce = vnt.core.getTransactionCount(from);

    // Generate transaction structure, specify to, nonce, gaspierce, gaslimit, value, data and other fields
    // Where the to field is the contract address and the data field is the data called by the contract
    var options = {
       to: contractAddr,
       nonce: vnt.toHex(nonce),
       gasPrice: vnt.toHex(30000000000000),
       gasLimit: vnt.toHex(4000000),
       value: '0x00',
       data: data
    }

    // Generate transaction
    var tx = new Tx(options);
    // Use the prepared private key to sign the transaction
    tx.sign(new Buffer(keyMap[from].privateKey.substring(2,), "hex"));

    // Serialize transaction data
    var serializedTx = tx.serialize();

    // Send transaction
    vnt.core.sendRawTransaction('0x' + serializedTx.toString('hex'),
    function(err, txHash) {
      if (err) {
          console.log("err happened: ", err)
      } else {
          // Print hash of transaction
          console.log("transaction hash: ", txHash);
          // Get list of transactions
          getTransactionReceipt(txHash, function(receipt) {
              console.log("tx receipt: ", receipt)
              console.log("tx status: ", receipt.status)
              console.log("contract address: ", receipt.contractAddress)
              GetAmount(to)
          })
      }
    });
}

reference material

VNT Javascript API

Tags: Blockchain

Posted on Thu, 18 Nov 2021 08:40:45 -0500 by shlomikalfa