Familiarizarse con el cliente geth y dentro de un código siguió un tutorial ( AQUÍ ) para transferir tokens desde una dirección. Cuando verifico la transacción en EtherScan, ha fallado:
https://rinkeby.etherscan.io/tx/0xf53488d996a532ae78080a23c54384c8f58438db02130f039b0e08dacf760f86
No estoy muy seguro de cómo depurar esto y agradecería cualquier sugerencia al respecto.
Aquí está la copia de mi código
package main
import (
"context"
"crypto/ecdsa"
"fmt"
"log"
"math/big"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
client, err := ethclient.Dial("https://rinkeby.infura.io")
if err != nil {
log.Fatal(err)
}
privateKey, err := crypto.HexToECDSA("49be7f9b459942977f07f99653b5b042144baefa092c5ac833d6ec9893a5b8dd")
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("error casting public key to ECDSA")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
log.Fatal(err)
}
value := big.NewInt(0) // Transfering Tokens doesnt need ETH values
//gasLimit := uint64(21000)
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Fatal(err)
}
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
tokenAddress := common.HexToAddress("0x28b149020d2152179873ec60bed6bf7cd705775d")
transferFnSignature := []byte("transfer(address,uint256")
hash := sha3.NewKeccak256()
hash.Write(transferFnSignature)
methodID := hash.Sum(nil)[:4] // read up go lang slices
fmt.Println(hexutil.Encode(methodID))
paddedAddress := common.LeftPadBytes(toAddress.Bytes(), 32)
fmt.Println(hexutil.Encode(paddedAddress))
amount := new(big.Int)
amount.SetString("1000000000000000000000", 10)
paddedAmount := common.LeftPadBytes(amount.Bytes(), 32)
fmt.Println(hexutil.Encode(paddedAmount))
var data []byte
data = append(data, methodID...)
data = append(data, paddedAddress...)
data = append(data, paddedAmount...)
gasLimit, err := client.EstimateGas(context.Background(), ethereum.CallMsg{
To: &toAddress,
Data: data,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(gasLimit)
/*
Generate Transation Type
*/
tx := types.NewTransaction(nonce, tokenAddress, value, gasLimit, gasPrice, data)
/*
Signing Tx with Sender's Private Key
*/
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, privateKey)
if err != nil {
log.Fatal(err)
}
/*
Broadcasting Transaction to Network
*/
err = client.SendTransaction(context.Background(), signedTx)
if err != nil {
log.Fatal(err)
}
fmt.Printf(" tx sent: %s\n", signedTx.Hash().Hex())
}
La firma de su función es incorrecta. Le falta un paréntesis derecho. Esta línea:
transferFnSignature := []byte("transfer(address,uint256")
debería ser esto en su lugar:
transferFnSignature := []byte("transfer(address,uint256)")
unable to locate transfer log
rinkeby.etherscan.io/tx/…
usuario19510
transfer(address,uint256)
, que luego se codifica con keccak256 para obtener el prefijo de 4 bytes0xa9059cbb
, pero su transacción comienza con0x30c48a31
.