使用簽名交易自動將號碼註冊到 Kovan 測試網(Infura API + NodeJS)
我使用 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();