shengbuchao

shengbuchao

web3 js coder

Node.js 編譯並部署智能合約

使用 solc-js 編譯部署合約。

初始化專案#

先建好資料夾和package.json#

mkdir test_deploy && cd test_deploy
npm init -y

添加web3,solc的依賴#

yarn add web3 solc

看好自己安裝的 solc 的版本號,需要和待會編寫使用solidity的版本號一致#

cat package.json

這時候終端顯示

{
  "name": "test_deploy",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "solc": "^0.8.16",
    "web3": "^1.7.5"
  }
}

那待會我們就使用solidity ^0.8.16;

編寫智能合約#

這裡我們就寫一個特別簡單的智能合約便於學習,新建callMe.sol文件。

// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.16;

contract CallMe {
    uint256 public CallMeNum = 0;
    
    function Ring() public {
        CallMeNum += 1;
    }
}

看代碼,我們就是簡單實現了一個計數功能,並沒有做很多的邏輯。大家可以根據自己的需求來改。

編譯並部署智能合約 (compile && deploy)#

新建index.js文件

這裡我們分為兩步

編譯 sol 文件 (compile)#

const solc = require('solc')
const fs = require('fs')
const source = fs.readFileSync('./callMe.sol', 'utf-8')
var input = {
    language: 'Solidity',
    sources: {
        'callMe.sol': {
            content: source
        }
    },
    settings: {
        outputSelection: {
            '*': {
                '*': ['*']
            }
        }
    }
};
const compiled = JSON.parse(solc.compile(JSON.stringify(input)))
const abi = compiled.contracts['callMe.sol']['CallMe']['abi']
const bytecode = compiled.contracts['callMe.sol']['CallMe']['evm']['bytecode']['object']
console.log({abi, bytecode});

這裡我們執行編譯,看到輸出如下

{
  abi: [
    {
      inputs: [],
      name: 'CallMeNum',
      outputs: [Array],
      stateMutability: 'view',
      type: 'function'
    },
    {
      inputs: [],
      name: 'Ring',
      outputs: [],
      stateMutability: 'nonpayable',
      type: 'function'
    }
  ],
  bytecode: '60806040526000805534801561001457600080fd5b50610151806100246000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806387b3be7d1461003b5780639c182ede14610045575b600080fd5b610043610063565b005b61004d61007e565b60405161005a919061009d565b60405180910390f35b600160008082825461007591906100e7565b92505081905550565b60005481565b6000819050919050565b61009781610084565b82525050565b60006020820190506100b2600083018461008e565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100f282610084565b91506100fd83610084565b9250828201905080821115610115576101146100b8565b5b9291505056fea26469706673582212208ff3edded4043aadbd02cd69f8cc8e59389aae986688e86065398a8c065e3c7464736f6c63430008100033'
}

這樣我們就得到了智能合約的 abi 和 bytecode。

部署合約 (deploy)#

const Web3 = require('web3');

const web3 = new Web3('https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')
const goerli_id = 5

const privateKey = '0x62.....58' // 私鑰

const deployAsync = async () => {
    // 函數裡abi,bytecode就是合約編譯出來的abi和bytecode
    const callMeContract = new web3.eth.Contract(abi)
    const deploy = callMeContract.deploy({ data: bytecode })
    const estimateGas = await deploy.estimateGas() // 從鏈上預跑估算所需的gasLimit
    const sign = await web3.eth.accounts.signTransaction({
        data: bytecode,
        gas: estimateGas * 2, // 為了防止gas不夠,這裡我們給兩倍的gas
        common: {
            customChain: {
                name: 'goerli',
                chainId: goerli_id,
                networkId: goerli_id
            }
        }
    }, privateKey)
    web3.eth.sendSignedTransaction(sign.rawTransaction)
        .on('transactionHash', function (hash) {
            console.log('transactionHash', { hash });
        })
        .on('receipt', function (receipt) {
            console.log('receipt', { receipt });
        })
        .on('error', console.error);
}

deployAsync()

ok,代碼寫完,下面我們執行編譯部署

node index.js

執行結果:

transactionHash {
  hash: '0xd76cd84f36c484128d74830c34441558e810126f4329664b6ecb79d67a9d5646'
}
receipt {
  receipt: {
    blockHash: '0x9ebc644fde5840ea2f5520e647ce135ddc464e926ed38ab98d4d2c83552c4215',
    blockNumber: 7496928,
    contractAddress: '0x2F644b5f5cee3174065264211B7c6466fDC997a9',
    cumulativeGasUsed: 17612622,
    effectiveGasPrice: 133182174,
    from: '0x3ecaa09dd6b8828607bba4b1d7055ea1143f8b94',
    gasUsed: 127863,
    logs: [],
    logsBloom: '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。