Web3js

使用簽名交易自動將號碼註冊到 Kovan 測試網(Infura API + NodeJS)

  • June 29, 2020

我使用 remix.ethereum 部署了一個非常簡單的智能合約,它是:

pragma solidity ^ 0.6.0;

contract primerContrato {

uint storeddata;

function set(uint x) public{
   storeddata = x;
}

function get() public view returns (uint){
   return storeddata;
}

}

我正在使用 Metamask 來測試 set 功能,它可以正常工作。我可以在 Etherscan 上看到我的交易雜湊和我在 Remix 上輸入的輸入。

我想自動執行此操作,而不必接受 Metamask 上的交易。我正在使用 NodeJS 生成文件,並且我想將它們的雜湊值儲存到測試網區塊鏈中。所以我會等待生成文件,然後呼叫我的智能合約的 set 函式來儲存該值。對於第一個測試,這將是一個帶有單個值要儲存的單個呼叫。

我一直在閱讀有關已簽名交易的一些資訊,並且我嘗試了來自https://medium.com/coinmonks/ethereum-tutorial-sending-transaction-via-nodejs-backend-7b623b885707的程式碼, 因為我沒有不需要網路程序來執行它:

const web3 = require('web3');
const express = require('express');
const Tx = require('ethereumjs-tx').Transaction;


//Infura HttpProvider Endpoint
web3js = new web3(new web3.providers.HttpProvider("https://kovan.infura.io/v3/APIKEY")); //there goes my API

enviar();

function enviar (req,res){

       var myAddress = '0x68d9...'; //from Metamask
       var privateKey = Buffer.from('42AE...', 'hex') //from Metamask
       var toAddress ; //no address as I am posting it to the smart contract

       //contract abi is the array that you can get from the ethereum wallet or etherscan
       var contractABI =[
                           {
                               "inputs": [],
                               "name": "get",
                               "outputs": [
                                   {
                                       "internalType": "uint256",
                                       "name": "",
                                       "type": "uint256"
                                   }
                               ],
                               "stateMutability": "view",
                               "type": "function"
                           },
                           {
                               "inputs": [
                                   {
                                       "internalType": "uint256",
                                       "name": "x",
                                       "type": "uint256"
                                   }
                               ],
                               "name": "set",
                               "outputs": [],
                               "stateMutability": "nonpayable",
                               "type": "function"
                           }
                       ];
       var contractAddress ="0xb031..."; //my contract address
       //creating contract object
       var contract = new web3js.eth.Contract(contractABI,contractAddress);

       var count;
       // get transaction count, later will used as nonce
       web3js.eth.getTransactionCount(myAddress).then(function(v){
           console.log("Count: "+v);
           count = v;
           var amount = web3js.utils.toHex(1e16);
           //creating raw tranaction
           var rawTransaction = {"from":myAddress, "gasPrice":web3js.utils.toHex(60* 1e9),"gasLimit":web3js.utils.toHex(3000000),"to":contractAddress,"value":"0x0","data":contract.methods.set(0x849787ab...).encodeABI(),"nonce":web3js.utils.toHex(count+2)}
           console.log(rawTransaction);
           //creating tranaction via ethereumjs-tx
           var transaction = new Tx (rawTransaction);
           //signing transaction with private key
           transaction.sign(privateKey);
           //sending transacton via web3js module
           web3js.eth.sendSignedTransaction('0x'+transaction.serialize().toString('hex'))
           .on('transactionHash',console.log);  

       })
   };

我發現了兩個錯誤:

第一個。當我嘗試在 上發送 256 位整數 (uint) 時contract.methods.set(0x849787ab...),控制台拋出溢出錯誤 (1e77)

第二。如果我將此值更改為較小的值,它實際上會顯示交易雜湊,但我不會在我的錢包上收取任何費用,因此我不會出現在 etherscan 上。

有沒有更簡單的方法可以做到這一點?你有任何疑問嗎?

先感謝您!我急於發送這個項目,非常感謝您的幫助!!!

當我嘗試在 上發送 256 位整數 (uint) 時contract.methods.set(0x849787ab...),控制台拋出溢出錯誤 (1e77)

在 Javascript 中,Number.MAX_SAFE_INTEGER等於 2 ^ 53 - 1。

因此,始終使用字元串:contract.methods.set("0x849787ab...").


有沒有更簡單的方法可以做到這一點?

這是我使用的(使用 web3.js v1.2.1 測試):

const Web3 = require("web3");

const YOUR_NODE_ADDRESS = "...";
const YOUR_PRIVATE_KEY  = "...";
const YOUR_INPUT_VALUE  = "...";
const YOUR_GAS_PRICE    = "...";

async function send(web3, account, gasPrice, transaction, value = 0) {
   const options = {
       to      : transaction._parent._address,
       data    : transaction.encodeABI(),
       gas     : await transaction.estimateGas({from: account.address, value: value}),
       gasPrice: gasPrice,
       value   : value
   };
   const signed  = await web3.eth.accounts.signTransaction(options, account.privateKey);
   const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
   return receipt;
}

async function run() {
   const web3 = new Web3(YOUR_NODE_ADDRESS);
   const contract = new web3.eth.Contract(contractABI,contractAddress);
   const account = web3.eth.accounts.privateKeyToAccount(YOUR_PRIVATE_KEY);
   const transaction = contract.methods.set(YOUR_INPUT_VALUE);
   const receipt = await send(web3, account, YOUR_GAS_PRICE, transaction);
   console.log(receipt);
}

run();

引用自:https://ethereum.stackexchange.com/questions/84628