I would like to write the Ethereum blockchain with a contract call. I already found two solutions which are almost the same, but one of them is manipulating the signed transaction, doing some byte encodings before sending it and I couldn't figure out why. My question is that why solution #2 and solution #3 uses the extra lines compared to solution #1? What is the purpose of the extra byte manipulation part? signedTx
and txToSend are both *types.Transaction
types, I don't understand why is it needed to do the encodings. The documentation of the go-ethereum package states that:
SendTransaction injects a signed transaction into the pending pool for execution.
It doesn't give further information about the tx and types.SignTx()
returns *types.Transaction
type.
Solution #1
This is the simplest solution without doing any manipulation with signedTx
.
tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
log.Fatal(err)
}
txErr := client.SendTransaction(context.Background(), tx)
if txErr != nil {
log.Fatalf("Error calling contract: %v", err)
}
Solution #2
This is the implementation used by the Go Ethereum Book's creating raw transaction and sending raw transaction part.
tx_signed := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
signedTx, err := types.SignTx(tx_signed, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
log.Fatal(err)
}
ts := types.Transactions{signedTx}
rawTxBytes := ts.GetRlp(0)
rawTxHex := hex.EncodeToString(rawTxBytes)
rawBytes, err := hex.DecodeString(rawTxHex)
tx := new(types.Transaction)
rlp.DecodeBytes(rawBytes, &tx)
txErr := client.SendTransaction(context.Background(), tx)
if txErr != nil {
log.Fatalf("Error calling contract: %v", err)
}
Solution #3
This implementation is almost the same as the previous, but it uses the newer EncodeIndex(i int, w *bytes.Buffer)
function for the byte manipulation. Source
tx_signed := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
signedTx, err := types.SignTx(tx_signed, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
log.Fatal(err)
}
ts := types.Transactions{signedTx}
b := new(bytes.Buffer)
ts.EncodeIndex(0, b)
rawTxBytes := b.Bytes()
txToSend := new(types.Transaction)
rlp.DecodeBytes(rawTxBytes, &txToSend)
txErr := client.SendTransaction(context.Background(), tx)
if txErr != nil {
log.Fatalf("Error calling contract: %v", err)
}