web3.js 执行写函数调用

执行写函数调用,需要签署交易、广播交易,就像前面章节中一样。

app.js

完整代码如下所示:

var Tx     = require('ethereumjs-tx').Transaction
const Web3 = require('web3')
const web3 = new Web3('https://ropsten.infura.io/v3/YOUR_INFURA_API_KEY')

const account1 = '0xf4Ab5314ee8d7AA0eB00b366c52cEEccC62d6B4B' // Your account address 1
const account2 = '0xff96B8B43ECd6C49805747F94747bFfa3A960b69' // Your account address 2

const pk1 = 'b75e2bcaec74857cf9bb6636d66a04784d4c0fcfd908f4a2bc213428eba5af0d' // 实际项目中应该从process.env.PRIVATE_KEY_1中读取
const pk2 = 'ac0adfdbaeb0770a479e79aac78779d82fdc2f9262e0c8f751ae70fb63ef6196' // 实际项目中应该从process.env.PRIVATE_KEY_2中读取

const privateKey1 = Buffer.from(pk1, 'hex')
const privateKey2 = Buffer.from(pk2, 'hex')

// 读取已部署的契约 -- 从Etherscan获取地址
const contractAddress = '0x30951343d6d80d2c94897f1a81c53cc030aef879'
const contractABI = [
    {
        "constant": false,
        "inputs": [
            {
                "internalType": "string",
                "name": "_value",
                "type": "string"
            }
        ],
        "name": "set",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "get",
        "outputs": [
            {
                "internalType": "string",
                "name": "",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "constructor"
    }
]

const contract = new web3.eth.Contract(contractABI, contractAddress)

web3.eth.getTransactionCount(account1, (err, txCount) => {

  // 创建交易对象
  const txObject = {
    nonce:    web3.utils.toHex(txCount),
    gasLimit: web3.utils.toHex(8000000),
    gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei')),
    to: contractAddress,
    data: contract.methods.set("qikegu").encodeABI()
  }

  // 签署交易
  const tx = new Tx(txObject, { chain: 'ropsten', hardfork: 'petersburg' })
  tx.sign(privateKey1)

  const serializedTx = tx.serialize()
  const raw = '0x' + serializedTx.toString('hex')

  // 广播交易
  web3.eth.sendSignedTransaction(raw, (err, txHash) => {
    console.log('txHash:', txHash)
    // 可以去ropsten.etherscan.io查看交易详情
  })

})

调用合约get()函数读取原来的value值

在执行合约set()函数调用之前,我们先看看原来的value值,新建一个get_val.js文件:

var Tx     = require('ethereumjs-tx').Transaction
const Web3 = require('web3')
const web3 = new Web3('https://ropsten.infura.io/v3/YOUR_INFURA_API_KEY')

const account1 = '0xf4Ab5314ee8d7AA0eB00b366c52cEEccC62d6B4B' // Your account address 1
const account2 = '0xff96B8B43ECd6C49805747F94747bFfa3A960b69' // Your account address 2

const pk1 = 'b75e2bcaec74857cf9bb6636d66a04784d4c0fcfd908f4a2bc213428eba5af0d' // 实际项目中应该从process.env.PRIVATE_KEY_1中读取
const pk2 = 'ac0adfdbaeb0770a479e79aac78779d82fdc2f9262e0c8f751ae70fb63ef6196' // 实际项目中应该从process.env.PRIVATE_KEY_2中读取

const privateKey1 = Buffer.from(pk1, 'hex')
const privateKey2 = Buffer.from(pk2, 'hex')

// 读取已部署的契约 -- 从Etherscan获取地址
const contractAddress = '0x30951343d6d80d2c94897f1a81c53cc030aef879'
const contractABI = [
    {
        "constant": false,
        "inputs": [
            {
                "internalType": "string",
                "name": "_value",
                "type": "string"
            }
        ],
        "name": "set",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "get",
        "outputs": [
            {
                "internalType": "string",
                "name": "",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "constructor"
    }
]

const contract = new web3.eth.Contract(contractABI, contractAddress)

// 读取val值
contract.methods.get().call((err, val) => {
  console.log({ err, val })
})

运行get_val.js:

$ node get_val

输出

myValue

执行app.js

运行app.js:

$ node app

输出

txHash: 0xcb538e0e2e08d3b352aeef34d0c31140f022d1ef456b89edb39972536dba259e

可以去etherscan,查看交易详情。

再次调用合约get()函数读取改变后的value值

过5分钟左右,让交易写入区块链。然后运行get_val.js:

$ node get_val

输出

{ err: null, val: 'qikegu' }

可以看到合约中value值,已经被成功改变。

web3.js 智能合约事件:以太坊智能合约能够发出事件,表示在智能合约代码执行中发生的事情。智能合约的前端UI,例如,DApps、web3.js,都可以侦听这些事件。 事件在区块链中的存储区块链是一个由区块组成的列表,这些块的内容基本上 ...