【阿菜用工具】利用 Web3.js 在 ganache 上部署以及调用智能合约

时间:2023-03-09 16:34:15
【阿菜用工具】利用 Web3.js 在 ganache 上部署以及调用智能合约

合约部署

要部署的合约

pragma solidity ^0.4.23;
contract test {
uint256 value; function setValue(uint256 _value) public{
value = _value;
} function getValue() public returns (uint256){
return value;
} function () public payable{ }
}

获取合约的ABI和bytecode

合约ABI

[
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"constant": false,
"inputs": [
{
"name": "_value",
"type": "uint256"
}
],
"name": "setValue",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "getValue",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]

合约bytecode

// add '0x' in front of the bytecode
0x608060405234801561001057600080fd5b5060dc8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632096525514604b57806355241077146073575b005b348015605657600080fd5b50605d609d565b6040518082815260200191505060405180910390f35b348015607e57600080fd5b50609b6004803603810190808035906020019092919050505060a6565b005b60008054905090565b80600081905550505600a165627a7a72305820437e5b6f23c9e202f4188fde72ebdd65de3a5c7fca347bea516a2f576748a9240029

部署代码

const Web3 = require('web3')
// RPC SERVER
const web3 = new Web3('http://localhost:7545')
var Tx = require('ethereumjs-tx').Transaction // your account and private key
const account = '0x1275270073b7CA41Cd1a62736795f80f7b52487c'
const pk1 = '56a0717cbc04b0e47732d5be497ad57052594c03088b9ef889fefca107ffeecb'
const private_key = Buffer.from(pk1, 'hex') // get the nonce of account
web3.eth.getTransactionCount(account, (err, txCount) => { // the bytecode of contract
const data = "0x608060405234801561001057600080fd5b5060dc8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632096525514604b57806355241077146073575b005b348015605657600080fd5b50605d609d565b6040518082815260200191505060405180910390f35b348015607e57600080fd5b50609b6004803603810190808035906020019092919050505060a6565b005b60008054905090565b80600081905550505600a165627a7a72305820437e5b6f23c9e202f4188fde72ebdd65de3a5c7fca347bea516a2f576748a9240029" // set transaction object
const txObject = {
nonce: web3.utils.toHex(txCount),
gasLimit: web3.utils.toHex(6721975),
gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei')),
data: data
} // sign transaction
const tx = new Tx(txObject)
tx.sign(private_key) const serializedTx = tx.serialize()
const raw = '0x' + serializedTx.toString('hex') // send transaction
web3.eth.sendSignedTransaction(raw, (err, txHash) => {
console.log('txHash:', txHash)
})
})

运行结果

【阿菜用工具】利用 Web3.js 在 ganache 上部署以及调用智能合约

注意一个问题,和利用 truffle 部署的智能合约不同,直接用 Web3.js 部署的合约是不会显示在 ganache 的 Contract页面里的,也就是说,它存在,只是没显示。

合约调用

调用代码

var Tx     = require('ethereumjs-tx').Transaction
// search their github for the detail of usage of 'Common' class
const Common = require('ethereumjs-common').default
const Web3 = require('web3')
const web3 = new Web3('http://localhost:7545') const account = '0x1275270073b7CA41Cd1a62736795f80f7b52487c'
const pk1 = '56a0717cbc04b0e47732d5be497ad57052594c03088b9ef889fefca107ffeecb'
const private_key = Buffer.from(pk1, 'hex') const contractAddress = '0x6F20B2F0149A680116411a01d5Bc6D4B09E869F4'
const contractABI = [
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"constant": false,
"inputs": [
{
"name": "_value",
"type": "uint256"
}
],
"name": "setValue",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "getValue",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
] // initialize the contract object
const contract = new web3.eth.Contract(contractABI, contractAddress) // call the setValue() function with parameter 123
const calldateABI = contract.methods.setValue(123).encodeABI() // All of these network's params are the same than mainnets', except for name, chainId, and
// networkId, so we use the Common.forCustomChain method.
const customCommon = Common.forCustomChain(
'mainnet',
{
// set the parameter as your ganache
name: 'my-network',
networkId: 5777,
chainId: 1337,
},
'petersburg',
) web3.eth.getTransactionCount(account, (err, count) => {
const txObject = {
nonce: web3.utils.toHex(count),
// set the gas limit as same as of ganache's
gasLimit: web3.utils.toHex(6721975),
gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei')),
to: contractAddress,
// contract.methods.<function name>(<parameter>).encodeABI()
data: contract.methods.setValue(123).encodeABI()
} // We pass our custom Common object whenever we create a transaction
const transaction = new Tx(txObject, { common: customCommon },)
console.log('transaction:', transaction) // sign the transaction
transaction.sign(private_key)
console.log('transaction.sign:', transaction) // returns the rlp encoding of the transaction
const serializedTx = transaction.serialize()
const raw = '0x' + serializedTx.toString('hex') web3.eth.sendSignedTransaction(raw, (err, txHash) => {
console.log('txHash:', txHash)
if(err){
throw err;
}
})
})

运行结果

【阿菜用工具】利用 Web3.js 在 ganache 上部署以及调用智能合约

参考文章

  1. 奇客谷:web3.js 教程
  2. 关于ethereumjs-tx在私链部署
  3. ethereumjs-common 调用方法