Сам спросил, сам и отвечу.
Решение, как выяснилось, лежало немного в иной плоскости. Вот код:
const
tokenAddress = '0x58....e4',
fromAddress = '0xaA....46c',
privateKey = '0x09........79',
toAddress = '0xE3....f7',
decimals = web3.utils.toBN(0),
amount = web3.utils.toBN(5),
value = amount.mul(web3.utils.toBN(10).pow(decimals)), // value = 5 = 5*(10^0)
sender = web3.eth.accounts.privateKeyToAccount(privateKey),
token = abi => new web3.eth.Contract(abi, tokenAddress).methods;
axios.get('https://api.etherscan.io/api?module=contract&action=getabi&address=' + tokenAddress)
.then(answer => {
const
abi = JSON.parse(answer.data.result),
data = token(abi)["transfer"](toAddress, value).encodeABI(),
tx = {
gas: '2000000',
from: fromAddress,
to: tokenAddress,
data,
};
token(abi).name().call().then(console.log);
token(abi).symbol().call().then(console.log);
token(abi).balanceOf(fromAddress).call().then(console.log);
sender.signTransaction(tx)
.then(signedTx => {
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.then(console.log);
});
});
Судя по всему, проблема была в том, что транзакция не была подписана. Так как перевод токенов, это не отправка какого-нибудь сообщения в духе "Hello world!", а вполне себе переброска реальных бабок, такая транзакция не может осуществляться с кошелька хозяина без его ведома. В статье How to send ERC20 token with Web3.js@1.0.0, ссылку на которую я приводил выше, и которой я руководствовался в процессе написания первоначального варианта кода, этот момент как-то странно обойдён автором. Если придирчиво изучить
демо-сайт, ссылку на него Hideyoshi Moriya приводит в конце своей статьи, можно заметить, что автор использует MetaMask API, что многое объясняет, но о чём ни слова нет в самой статье. Судя по всему, MetaMask позволяет решить вопрос авторизации своими методами.
Я же продолжил свои исследования. Усиленно копая интернет, через достаточно небольшой промежуток времени, наткнулся на аналогичный моему вопрос человека с ником
Dmitry на русском сегменте
StackOverflow.com:
Как отправить токены ethereum с помощью web3.js. Цитировать его я не буду, но вот ответ человека с ником
user3655581 привлёк моё внимание:
Для того, чтобы перевести токены - нужно вызвать соответствующий метод контракта токена, предварительно его подписав. Примерный код:
const sender = web3.eth.accounts.privateKeyToAccount(privateKeyFrom);
const tokenContract = new web3.eth.Contract(abi, contractAddress);
const data = tokenContract.methods["transfer"](toAddress, amount).encodeABI();
const tx = {
gas: '2000000',
from: fromAddress,
to: contractAddress,
data,
};
const signedTx = await sender.signTransaction(tx);
const result = await web3.eth
.sendSignedTransaction(signedTx.rawTransaction);
Руководствуясь приведённым кодом, я соорудил решение для своей задачи. Токены в количестве 5 штук успешно переправлены с одного кошелька на другой.
Спасибо большое всем, кто хотел мне помочь в этом вопросе, но немного не успел. Если у кого есть что добавить — буду только рад вашим комментариям. потому что пока очень и очень смутно ориентируюсь в поднятом вопросе.