#javascript #node.js #ethereum #web3
Вопрос:
Обзор
Всем привет, я не разработчик и не программист, но я запустил эту программу Udacity Blockchain Nanodegree и начал программировать некоторые приложения для блокчейна.
С курса я начал кодировать простую программу для отправки некоторого количества эфира с одной учетной записи Metamask на другую, обе учетные записи находятся в одной тестовой сети (Rinkeby).
Это то, что я использую для программы до сих пор:
- Метамаска с 2 учетными записями в тестовой сети Ринкеби.
- Версия Web3 1.5.1
- ethereumjs-tx версия 2.1.2
- Конечная точка Инфура Ринкеби
проблема
Проблема в том, что курс устарел, и большая часть их кода больше не работает. Итак, я начал реализовывать свой код после 3 дней поиска на веб-сайте Web3 ( ссылка: https://web3js.readthedocs.io/en/v1.4.0/index.html ), мне удалось написать код, который вы можете увидеть во фрагменте.
Код не выдает ошибок с моей стороны, и когда я проверяю количество транзакций (в том числе ожидающих), количество транзакций продолжает увеличиваться каждый раз, когда я запускаю свой код. Но, когда я проверяю веб-сайт Rinkeby Etherscan ( ссылка: https://rinkeby.etherscan.io/ ), транзакции нигде не отображаются в списке транзакций (завершенные, незавершенные, неудачные, исходящие и входящие транзакции).
вопросы
- В чем проблема с моим кодом? Как я могу это/их решить?
- Как я могу рассчитать gasPrice и как определить газовый климат? Я хочу только совершить транзакцию, чтобы отправить X-количество эфира без данных.
- Я попытался использовать тот же gasPrice и gasLimit, что и Metamask, но это привело меня к ошибке «Внутренний газ слишком низкий». Почему это происходит? Потому что у меня не было проблем с использованием этих значений в Metamask, и транзакция для отправки эфира с одной учетной записи metamask на другую заняла менее 3 минут (я отправил транзакцию из плагина Metamask).
- Имеет ли вилка цепи какое-либо отношение к этой проблеме? Если да, то как мне проверить правильную вилку для двух моих учетных записей в Metamask?
записка
Я передаю через код закрытый ключ для учетной записи senderAccount, потому что эти 2 учетные записи предназначены только для тестирования этого конкретного кода в тестовой сети Rinkeby. Я не планирую использовать их в качестве кошельков.
код
// STEP 1: LOADING DEPENDENCIES
const Web3 = require('web3');
const web3 = new Web3('https://rinkeby.infura.io/v3/4fa53ccf01504cc69f0dcbdfdaa38acf');
const Transaction = require('ethereumjs-tx').Transaction;
async function sendTransaction() {
// STEP 2: INSTANCIATING ADDRESSES
const sendingAddress = '0x5Be6e93fE99374E506F4e3803e91EbDFe35D6A39';
const receivingAddress = '0x24620ddf8474c89C0Fc0c916acBcF4029C4eB47F';
// STEP 3: CONSTRUCTING THE TRANSACTION
const rawTx = {
from : web3.utils.toHex(sendingAddress),
to : web3.utils.toHex(receivingAddress),
value : web3.utils.toHex(900000000000000),
gasPrice : web3.utils.toHex(1000000000),
gasLimit : web3.utils.toHex(210000),
data : web3.utils.toHex(''),
nonce : web3.utils.toHex(await web3.eth.getTransactionCount(sendingAddress, 'pending')),
};
// STEP 4: GENERATING PRIVATE KEY FROM PRIVATE KEY OF ACCOUNT
const privateKey = Buffer.from('e603c35185142cc8779c47f9c88a81a52446aaa1398286abf3340178aee11c36', 'hex');
// STEP 5: INITIALIZATING THE TRANSACTION
const tx = new Transaction(rawTx, { chain: 'rinkeby', hardfork: 'istanbul' });
// STEP 6: SIGN TRANSACTION
tx.sign(privateKey);
// STEP 7: SERIALIZE TRANSACTION
const serializedTx = tx.serialize();
web3.eth.sendSignedTransaction('0x' serializedTx.toString('hex')).on('receipt', console.log);
// BONUS: CHECKING NUMBER OF TRANSACTIONS
console.log(await web3.eth.getTransactionCount(sendingAddress, 'pending'));
}
sendTransaction();
Ответ №1:
Хорошо, я обнаружил, что код был неполным, и мне нужно было реализовать больше вещей. Вот код завершен и работает на 100%.
// THIS IS THE LEGACY FORM TO SEND TRANSACTIONS
// Loading dependencies
const fs = require( 'fs' ).promises;
const Web3 = require( 'web3' );
const HDWalletProvider = require( '@truffle/hdwallet-provider' );
const { mnemonicGenerate } = require( '@polkadot/util-crypto' );
const Transaction = require('ethereumjs-tx').Transaction;
const Common = require('ethereumjs-common').defau<
async function main () {
// Infura rinkeby's url
const infuraRinkeby = INFURA_HTTPS;
// Generating bip39 mnemonic
// const mnemonic = mnemonicGenerate();
// save the mnemonic in a JSON file in your project directory
// console.log(mnemonic);
// Loading previously generated mnemonic
const mnemonic = ( JSON.parse( await fs.readFile(
"FILE_WITH_MNEMONIC.json" ,
"utf8"
) ) ).mnemonic;
// Generating provider
const provider = new HDWalletProvider( mnemonic , infuraRinkeby );
const web3 = new Web3( provider );
// Declaring rinkeby testnet
const chain = new Common( 'rinkeby' , 'istanbul' );
// Getting sending and receiving addresses
//YOU CAN CHANGE 0 TO SELECT OTHER ADDRESSES
const sendingAddress = ( await web3.eth.getAccounts() )[0];
const receivingAddress = "DESTINATION_ADDRESS";
// Getting the private key for the account
const preKey = ( provider.wallets )[ sendingAddress.toLowerCase() ]
.privateKey.toString( 'hex' );
const privateKey = Buffer.from( preKey , 'hex' );
// Constructing the raw transaction
const rawTx = {
from : web3.utils.toHex( sendingAddress ),
to : web3.utils.toHex( receivingAddress ),
gasPrice : web3.utils.toHex( web3.utils.toWei( '1' , 'gwei' ) ),
gasLimit : web3.utils.toHex( 200000 ),
value : web3.utils.toHex( web3.utils.toWei( '0.25' , 'ether' ) ),
data : web3.utils.toHex( 'Hello World!' ),
nonce : web3.utils.toHex( await web3.eth.getTransactionCount(
sendingAddress ,
'pending'
) ),
};
// Creating a new transaction
const tx = new Transaction( rawTx , { common : chain } );
// Signing the transaction
tx.sign( privateKey );
// Sending transaction
await web3.eth.sendSignedTransaction( '0x' tx.serialize().toString( 'hex' ) )
.on( 'receipt', function( receipt ) {
console.log( receipt );
})
.on( 'error' , function( error ) {
console.error( error );
});
};
main();