Ich muss eine Offline-Transaktion in Golang unterzeichnen. Ich habe Folgendes, was eine leichte Modifikation dieser Antwort auf eine ähnliche Frage ist:
import "github.com/ethereum/go-ethereum/core/types"
import "github.com/ethereum/go-ethereum/common"
import "github.com/ethereum/go-ethereum/crypto"
type GethTxn struct {
To string `json:"to"`
From string `json:"from"`
Gas string `json:"gas"`
GasPrice string `json:"gasPrice"`
Value string `json:"value"`
Data string `json:"input"`
}
func SignTxn(from string, _to string, data []byte, nonce uint64, value int64, gas *big.Int, gasPrice *big.Int, privkey *ecdsa.PrivateKey) (*GethTxn, error) {
var parsed_tx = new(GethTxn)
var amount = big.NewInt(value)
var bytesto [20]byte
_bytesto, _ := hex.DecodeString(_to[2:])
copy(bytesto[:], _bytesto)
to := common.Address([20]byte(bytesto))
signer := types.NewEIP155Signer(nil)
tx := types.NewTransaction(nonce, to, amount, gas, gasPrice, data)
signature, _ := crypto.Sign(tx.SigHash(signer).Bytes(), privkey)
signed_tx, _ := tx.WithSignature(signer, signature)
json_tx, _ := signed_tx.MarshalJSON()
_ = json.Unmarshal(json_tx, parsed_tx)
parsed_tx.From = from
fmt.Println("data", parsed_tx.Data)
return parsed_tx, nil
}
Was ich will, ist die rohe Transaktionsnutzlast, aber was ich bekomme, ist falsch. Ich glaube, ich will parsed_data.Data
, aber ich bin mir nicht sicher. Was ich suche, ist ein Go-Analog zur folgenden JS-Funktion:
var Tx = require('ethereumjs-tx');
var privateKey = new Buffer(pkey, 'hex')
var tx = new Tx(txn);
tx.sign(privateKey);
var serializedTx = tx.serialize().toString('hex')
Wo serializedTx
ist eine Zeichenfolge (die gewünschte Nutzlast).
Ich bin ein Golang-Noob, also vermute ich, dass ich Geth nur missbrauche, aber jede Hilfe wäre sehr willkommen. Ich habe ziemlich lange mit diesem Problem verbracht.
Sie können zwei Methoden verwenden, um das Rohtransaktions-RLP zu erhalten
Rufen Sie die String()
der signierten Transaktion ab. Sie können es direkt aufrufen oder es die fmt
Bibliothek für Sie erledigen lassen:
my_string_var = signed_tx.String()
oder
my_string_var = fmt.Sprintf("%v", signed_tx)
Das Problem ist, dass Sie die Ausgabe analysieren müssen, die so etwas wie sein wird
TX(57c9544749f223acdff0be77876a4a45125cef360530caa97a92c359e4d7a6ce)
Contract: false
From: 1600da1bcbef5599e09532f230ced99db0619b95
To: 1737b4e8e4101334b1b1965d3d739c41cc54f096
Nonce: 0
GasPrice: 0x1bc16d674ec80000
GasLimit 0x186a0
Value: 0x0
Data: 0xdeaa59df000000000000000000000000cbfdfb9fb838b9090a7fe1976ed98017632b44f1
V: 0x78
R: 0xa484a59015d08e736f59edf07ffb32f73151fddec52885b1f29cbcfd7aac203
S: 0x842a3a63c2fb1771cd0495b93a4db94692d4733baa9e96c559ddc4ff600422
Hex: f88b80881bc16d674ec80000830186a0941737b4e8e4101334b1b1965d3d739c41cc54f09680a4deaa59df000000000000000000000000cbfdfb9fb838b9090a7fe1976ed98017632b44f178a00a484a59015d08e736f59edf07ffb32f73151fddec52885b1f29cbcfd7aac2039f842a3a63c2fb1771cd0495b93a4db94692d4733baa9e96c559ddc4ff600422
Verwenden Sie stattdessen die Methode GetRlp()
der Struktur Transactions
(Plural, mit einem s).
Wir erstellen eine Variable ts
und füllen sie mit dieser signierten Transaktion
ts := types.Transactions{signed_tx}
Dann rufen wir einfach auf
my_string_var = fmt.Sprintf("%x", ts.getRlp(0))
Welche die gewünschte rohe Transaktionszeichenfolge enthalten wird
f88b80881bc16d674ec80000830186a0941737b4e8e4101334b1b1965d3d739c41cc54f09680a4deaa59df000000000000000000000000cbfdfb9fb838b9090a7fe1976ed98017632b44f178a00a484a59015d08e736f59edf07ffb32f73151fddec52885b1f29cbcfd7aac2039f842a3a63c2fb1771cd0495b93a4db94692d4733baa9e96c559ddc4ff600422
Erstellen Sie eine Rohtransaktion:
package main
import (
"context"
"crypto/ecdsa"
"encoding/hex"
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"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("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
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(1000000000000000000) // in wei (1 eth)
gasLimit := uint64(21000) // in units
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Fatal(err)
}
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
var data []byte
tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
chainID, err := client.NetworkID(context.Background())
if err != nil {
log.Fatal(err)
}
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
log.Fatal(err)
}
ts := types.Transactions{signedTx}
rawTx := hex.EncodeToString(ts.GetRlp(0))
fmt.Printf(rawTx) // f86...772
}
Senden der Rohtransaktion:
package main
import (
"context"
"encoding/hex"
"fmt"
"log"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rlp"
)
func main() {
client, err := ethclient.Dial("https://rinkeby.infura.io")
if err != nil {
log.Fatal(err)
}
rawTx := "f86d8202b28477359400825208944592d8f8d7b001e72cb26a73e4fa1806a51ac79d880de0b6b3a7640000802ca05924bde7ef10aa88db9c66dd4f5fb16b46dff2319b9968be983118b57bb50562a001b24b31010004f13d9a26b320845257a6cfc2bf819a3d55e3fc86263c5f0772"
var tx *types.Transaction
rawTxBytes, err := hex.DecodeString(rawTx)
rlp.DecodeBytes(rawTxBytes, &tx)
err = client.SendTransaction(context.Background(), tx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("tx sent: %s", tx.Hash().Hex()) // tx sent: 0xc429e5f128387d224ba8bed6885e86525e14bfdc2eb24b5e9c3351a1176fd81f
}
„Erstellen von Offline-/Rohtransaktionen mit Go-Ethereum“ @akshay_111meher https://medium.com/@akshay_111meher/creating-offline-raw-transactions-with-go-ethereum-8d6cc8174c5d
ethereum_alex
data
Feld in einen der Geth-Typen umwandeln:common.FromHex(string(data))
, wo mydata
ist[]byte
.Cyberience
Enrique Alcázar