Skip to content

Instantly share code, notes, and snippets.

@0fuz
Last active April 16, 2022 13:59
Show Gist options
  • Save 0fuz/5c80252e748cfb9cad7568a513282398 to your computer and use it in GitHub Desktop.
Save 0fuz/5c80252e748cfb9cad7568a513282398 to your computer and use it in GitHub Desktop.
eth_bsc_wallet_template
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"encoding/json"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"io/ioutil"
"math/big"
"math/rand"
"strconv"
"sync"
"time"
)
// hexString without 0x
func toECDSAFromHex(hexString string) *ecdsa.PrivateKey {
pk := new(ecdsa.PrivateKey)
pk.D, _ = new(big.Int).SetString(hexString, 16)
pk.PublicKey.Curve = elliptic.P256()
pk.PublicKey.X, pk.PublicKey.Y = pk.PublicKey.Curve.ScalarBaseMult(pk.D.Bytes())
return pk
}
func LoadAccountsFromFile() []Account {
content, err := ioutil.ReadFile("./_accounts.json") // [{"address":"0x0000000000000","privateKey":"0x0000000000000"}]
var payload []AccountJson
err = json.Unmarshal(content, &payload)
if err != nil {
log.Error("Error during Unmarshal(): ", err)
panic(err)
}
var res []Account
for _, o := range payload {
pkWithout0x := o.PrivateKey[2:]
pk := toECDSAFromHex(pkWithout0x)
res = append(res, Account{
Address: common.HexToAddress(o.Address),
PrivateKey: pk,
})
}
}
func (a *Manager) GetSignedTx(
account Account,
gasPrice *big.Int,
gasLimit uint64,
to *common.Address,
value *big.Int,
data []byte,
) (signedTx *types.Transaction, err error, duration time.Duration) {
s := time.Now()
txTemp := types.NewTx(&types.LegacyTx{
Nonce: account.nonce,
GasPrice: gasPrice,
Gas: gasLimit,
To: to,
Value: value,
Data: data,
})
signedTx, err = types.SignTx(txTemp, Signer, account.PrivateKey)
if err != nil {
return signedTx, err, time.Since(s)
}
return signedTx, nil, time.Since(s)
}
// a.client *ethclient.Client
// client, err := ethclient.Dial("ws://127.0.0.1:8546") // стандартный путь к локальной ноде, подходит любой ws/https rpc от сюда https://docs.binance.org/smart-chain/developer/rpc.html
// a.client = client
// get wallet nonce
nonce, err := a.client.NonceAt(context.Background(), account.Address, nil) // lazy nonce (latest mined block nonce+)
nonce, err := a.client.PendingNonceAt(context.Background(), account.Address) // include pending tx nonce+1
err = a.client.SendTransaction(context.Background(), signedTx) // отправить транзакцию
@0fuz
Copy link
Author

0fuz commented Apr 12, 2022

поле Data содержит byte[0] или 0x_назавние_метода_аргумент1_аргумент2 (для аргумента адреса зарезервировано одно количество байт, для uint другое)

название_метода это хеш solidity метода

пример для transfer на solidity:

console.logBytes4(bytes4(keccak256(bytes('transfer(address,uint256)'))));    // 0xa9059cbb = название метода

'transfer(address,uint256)' это хранится в solidity Abi

типичный ERC20/BEP20 abi:

interface IERC20 {
    function balanceOf(address owner) external view returns (uint);
    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
}

// https://bscscan.com/address/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c#code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment