mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
add precompiled contract to get info from Algorand chain
This commit is contained in:
parent
a8617c6d4d
commit
494d69c269
18 changed files with 461 additions and 9 deletions
114
core/vm/algorand/input.go
Normal file
114
core/vm/algorand/input.go
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package algorand
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
)
|
||||
|
||||
type CmdType = uint8
|
||||
|
||||
const (
|
||||
// AccountCmd is the type of the command to get account information.
|
||||
AccountCmd CmdType = iota
|
||||
)
|
||||
|
||||
// Input is the interface for the input of the Algorand precompiled contract.
|
||||
type Input interface {
|
||||
GetCmdType() CmdType // GetCmdType returns the command type.
|
||||
GetFieldName() string // GetFieldName returns the name of the field to get.
|
||||
}
|
||||
|
||||
// AccountInput is the input for the command to get account information.
|
||||
type AccountInput struct {
|
||||
Cmd CmdType // Command type.
|
||||
FieldName string // Name of the field to get.
|
||||
Address string // Address of the account.
|
||||
}
|
||||
|
||||
// GetCmdType returns the command type.
|
||||
func (input *AccountInput) GetCmdType() CmdType {
|
||||
return input.Cmd
|
||||
}
|
||||
|
||||
// GetFieldName returns the name of the field to get.
|
||||
func (input *AccountInput) GetFieldName() string {
|
||||
return input.FieldName
|
||||
}
|
||||
|
||||
// getCmdTypeFromRawInput gets the command type from the raw input.
|
||||
func getCmdTypeFromRawInput(inputBytes []byte) (CmdType, error) {
|
||||
cmd := new(CmdType)
|
||||
err := unpack(inputBytes, cmd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return *cmd, nil
|
||||
}
|
||||
|
||||
// UnpackInput decodes the raw input into the input of the Algorand precompiled contract.
|
||||
func UnpackInput(inputBytes []byte) (Input, error) {
|
||||
cmd, err := getCmdTypeFromRawInput(inputBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch cmd {
|
||||
case AccountCmd:
|
||||
input := new(AccountInput)
|
||||
err = unpack(inputBytes, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return input, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown command type: %d", cmd)
|
||||
}
|
||||
}
|
||||
|
||||
// abiType returns the ABI of the given name and type.
|
||||
func abiType(name string, typ reflect.Type) string {
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
return abiType(name, typ.Elem())
|
||||
} else if typ.Kind() == reflect.Struct {
|
||||
var fields []string
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
fields = append(fields, abiType(typ.Field(i).Name, typ.Field(i).Type))
|
||||
}
|
||||
return strings.Join(fields, ", ")
|
||||
} else {
|
||||
return fmt.Sprintf(`{"name": "%s", "type": "%s"}`, name, typ.String())
|
||||
}
|
||||
}
|
||||
|
||||
// unpack decodes the raw data into the given output interface.
|
||||
func unpack(rawData []byte, output interface{}) error {
|
||||
typ := reflect.TypeOf(output)
|
||||
defn := fmt.Sprintf(`[{"type": "function", "outputs": [%s]}]`, abiType("", typ))
|
||||
abi, err := abi.JSON(strings.NewReader(defn))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = abi.UnpackIntoInterface(output, "", rawData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
43
core/vm/algorand/input_test.go
Normal file
43
core/vm/algorand/input_test.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package algorand
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetCmdType(t *testing.T) {
|
||||
data, err := common.ParseHexOrString("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||
require.NoError(t, err)
|
||||
cmd, err := getCmdTypeFromRawInput(data)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, AccountCmd, CmdType(cmd))
|
||||
}
|
||||
|
||||
func TestDecodeInput(t *testing.T) {
|
||||
data, err := common.ParseHexOrString("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000006416d6f756e740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a3733373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737375546454a324349000000000000")
|
||||
require.NoError(t, err)
|
||||
input, err := UnpackInput(data)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, AccountCmd, input.GetCmdType())
|
||||
// 737777777777777777777777777777777777777777777777777UFEJ2CI is the address of RewardsPool in the Algorand mainnet.
|
||||
require.Equal(t, "737777777777777777777777777777777777777777777777777UFEJ2CI", input.(*AccountInput).Address)
|
||||
require.Equal(t, "Amount", input.(*AccountInput).FieldName)
|
||||
}
|
||||
41
core/vm/algorand/output.go
Normal file
41
core/vm/algorand/output.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package algorand
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
func pack(value reflect.Value) ([]byte, error) {
|
||||
defn := fmt.Sprintf(`[{"type": "constructor", "inputs": [%s]}]`, abiType("", value.Type()))
|
||||
abi, err := abi.JSON(strings.NewReader(defn))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := abi.Pack("", value.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Info("Pack", "data", common.Bytes2Hex(data))
|
||||
return data, nil
|
||||
}
|
||||
81
core/vm/algorand/precompiled.go
Normal file
81
core/vm/algorand/precompiled.go
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package algorand
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/algorand/go-algorand-sdk/client/v2/algod"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// Algorand implements the precompile to access the Algorand blockchain.
|
||||
type Algorand struct {
|
||||
algodAddress string
|
||||
algodToken string
|
||||
algodClient *algod.Client
|
||||
}
|
||||
|
||||
// New creates a new Algorand precompiled contract with a client to access Algorand blockchain.
|
||||
func New() *Algorand {
|
||||
algodAddress := os.Getenv("ALGOD_ADDRESS")
|
||||
algodToken := os.Getenv("ALGOD_TOKEN")
|
||||
algorand := &Algorand{
|
||||
algodAddress: algodAddress,
|
||||
algodToken: algodToken,
|
||||
}
|
||||
algodClient, err := algod.MakeClient(algodAddress, algodToken)
|
||||
if err == nil {
|
||||
algorand.algodClient = algodClient
|
||||
}
|
||||
return algorand
|
||||
}
|
||||
|
||||
// RequiredGas estimates the gas required for running the point evaluation precompile.
|
||||
func (a *Algorand) RequiredGas(input []byte) uint64 {
|
||||
return params.AlgorandPrecompileGas
|
||||
}
|
||||
|
||||
// Run executes the Algorand precompile with the given input.
|
||||
func (a *Algorand) Run(input []byte) ([]byte, error) {
|
||||
if a.algodClient == nil {
|
||||
return nil, fmt.Errorf("cannot connect to Algorand node")
|
||||
}
|
||||
|
||||
params, err := UnpackInput(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var info interface{}
|
||||
switch params.GetCmdType() {
|
||||
case AccountCmd:
|
||||
info, err = a.algodClient.AccountInformation(params.(*AccountInput).Address).Do(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
log.Info("Algorand.Run", "info", info)
|
||||
value := reflect.ValueOf(info).FieldByName(params.GetFieldName())
|
||||
if !value.IsValid() {
|
||||
return nil, fmt.Errorf("field %s does not exist", params.GetFieldName())
|
||||
}
|
||||
return pack(value)
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/vm/algorand"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
||||
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
||||
|
|
@ -90,6 +91,7 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
|
|||
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||
common.BytesToAddress([]byte{0xff}): algorand.New(), // An instance of the Algorand precompiled contract
|
||||
}
|
||||
|
||||
// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum
|
||||
|
|
|
|||
22
demos/algorand/contracts/AlgorandInfo.sol
Normal file
22
demos/algorand/contracts/AlgorandInfo.sol
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.18;
|
||||
|
||||
contract AlgorandInfo {
|
||||
event Log(string message, uint256 value);
|
||||
|
||||
enum CmdType {
|
||||
AccountCmd
|
||||
}
|
||||
|
||||
function getAccountBalance(
|
||||
string memory accountAddress
|
||||
) public returns (uint256) {
|
||||
(bool ok, bytes memory data) = address(0xff).call(
|
||||
abi.encode(CmdType.AccountCmd, "Amount", accountAddress)
|
||||
);
|
||||
require(ok, "failed to get account balance");
|
||||
uint256 balance = abi.decode(data, (uint256));
|
||||
emit Log("balance", balance);
|
||||
return balance;
|
||||
}
|
||||
}
|
||||
10
demos/algorand/txs/1_deploy/alloc.json
Normal file
10
demos/algorand/txs/1_deploy/alloc.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"0x7ea155883a46dccf117972cb1e438fe5ec1c353c": {
|
||||
"balance": "0xffffffff",
|
||||
"nonce": "0x0"
|
||||
},
|
||||
"0xc207a7021fbef833a19f3688a5e7a8cf1e331391": {
|
||||
"balance": "0xffff",
|
||||
"nonce": "0x0"
|
||||
}
|
||||
}
|
||||
12
demos/algorand/txs/1_deploy/env.json
Normal file
12
demos/algorand/txs/1_deploy/env.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"currentCoinbase": "0xc207a7021fbef833a19f3688a5e7a8cf1e331391",
|
||||
"currentDifficulty": "0x1",
|
||||
"currentGasLimit": "0x05f5e100",
|
||||
"currentBaseFee": "0x1",
|
||||
"currentNumber": "0x01",
|
||||
"currentTimestamp": "0x03e8",
|
||||
"previousHash": "0xe729de3fec21e30bea3d56adb01ed14bc107273c2775f9355afb10f594a10d9e",
|
||||
"blockHashes": {
|
||||
"0": "0xe729de3fec21e30bea3d56adb01ed14bc107273c2775f9355afb10f594a10d9e"
|
||||
}
|
||||
}
|
||||
11
demos/algorand/txs/1_deploy/txn.json
Normal file
11
demos/algorand/txs/1_deploy/txn.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"from": "0x7ea155883a46dccf117972cb1e438fe5ec1c353c",
|
||||
"gas": "0xEFFFFF",
|
||||
"gasPrice": "0x1",
|
||||
"nonce": "0x0",
|
||||
"value": "0x0",
|
||||
"input": "0x608060405234801561001057600080fd5b506106bd806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c82b4dbb14610030575b600080fd5b61004a600480360381019061004591906102e8565b610060565b604051610057919061034a565b60405180910390f35b600080600060ff73ffffffffffffffffffffffffffffffffffffffff166000856040516020016100919291906104a7565b6040516020818303038152906040526040516100ad9190610531565b6000604051808303816000865af19150503d80600081146100ea576040519150601f19603f3d011682016040523d82523d6000602084013e6100ef565b606091505b509150915081610134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012b90610594565b60405180910390fd5b60008180602001905181019061014a91906105e0565b90507fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b58160405161017b9190610659565b60405180910390a1809350505050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6101f5826101ac565b810181811067ffffffffffffffff82111715610214576102136101bd565b5b80604052505050565b600061022761018e565b905061023382826101ec565b919050565b600067ffffffffffffffff821115610253576102526101bd565b5b61025c826101ac565b9050602081019050919050565b82818337600083830152505050565b600061028b61028684610238565b61021d565b9050828152602081018484840111156102a7576102a66101a7565b5b6102b2848285610269565b509392505050565b600082601f8301126102cf576102ce6101a2565b5b81356102df848260208601610278565b91505092915050565b6000602082840312156102fe576102fd610198565b5b600082013567ffffffffffffffff81111561031c5761031b61019d565b5b610328848285016102ba565b91505092915050565b6000819050919050565b61034481610331565b82525050565b600060208201905061035f600083018461033b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600181106103a5576103a4610365565b5b50565b60008190506103b682610394565b919050565b60006103c6826103a8565b9050919050565b6103d6816103bb565b82525050565b600082825260208201905092915050565b7f416d6f756e740000000000000000000000000000000000000000000000000000600082015250565b60006104236006836103dc565b915061042e826103ed565b602082019050919050565b600081519050919050565b60005b83811015610462578082015181840152602081019050610447565b60008484015250505050565b600061047982610439565b61048381856103dc565b9350610493818560208601610444565b61049c816101ac565b840191505092915050565b60006060820190506104bc60008301856103cd565b81810360208301526104cd81610416565b905081810360408301526104e1818461046e565b90509392505050565b600081519050919050565b600081905092915050565b600061050b826104ea565b61051581856104f5565b9350610525818560208601610444565b80840191505092915050565b600061053d8284610500565b915081905092915050565b7f6661696c656420746f20676574206163636f756e742062616c616e6365000000600082015250565b600061057e601d836103dc565b915061058982610548565b602082019050919050565b600060208201905081810360008301526105ad81610571565b9050919050565b6105bd81610331565b81146105c857600080fd5b50565b6000815190506105da816105b4565b92915050565b6000602082840312156105f6576105f5610198565b5b6000610604848285016105cb565b91505092915050565b7f62616c616e636500000000000000000000000000000000000000000000000000600082015250565b60006106436007836103dc565b915061064e8261060d565b602082019050919050565b6000604082019050818103600083015261067281610636565b9050610681602083018461033b565b9291505056fea2646970667358221220c3e34f0989dd6a37b0ef1efd133f9204e87676e4f623bd2ed7bdc6b7495c955464736f6c63430008150033",
|
||||
"r": "0x0",
|
||||
"s": "0x0",
|
||||
"v": "0x0"
|
||||
}
|
||||
1
demos/algorand/txs/1_deploy/txs.json
Normal file
1
demos/algorand/txs/1_deploy/txs.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
[{"type":"0x0","chainId":"0x3039","nonce":"0x0","to":null,"gas":"0xefffff","gasPrice":"0x1","maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x0","input":"0x608060405234801561001057600080fd5b506106bd806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c82b4dbb14610030575b600080fd5b61004a600480360381019061004591906102e8565b610060565b604051610057919061034a565b60405180910390f35b600080600060ff73ffffffffffffffffffffffffffffffffffffffff166000856040516020016100919291906104a7565b6040516020818303038152906040526040516100ad9190610531565b6000604051808303816000865af19150503d80600081146100ea576040519150601f19603f3d011682016040523d82523d6000602084013e6100ef565b606091505b509150915081610134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012b90610594565b60405180910390fd5b60008180602001905181019061014a91906105e0565b90507fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b58160405161017b9190610659565b60405180910390a1809350505050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6101f5826101ac565b810181811067ffffffffffffffff82111715610214576102136101bd565b5b80604052505050565b600061022761018e565b905061023382826101ec565b919050565b600067ffffffffffffffff821115610253576102526101bd565b5b61025c826101ac565b9050602081019050919050565b82818337600083830152505050565b600061028b61028684610238565b61021d565b9050828152602081018484840111156102a7576102a66101a7565b5b6102b2848285610269565b509392505050565b600082601f8301126102cf576102ce6101a2565b5b81356102df848260208601610278565b91505092915050565b6000602082840312156102fe576102fd610198565b5b600082013567ffffffffffffffff81111561031c5761031b61019d565b5b610328848285016102ba565b91505092915050565b6000819050919050565b61034481610331565b82525050565b600060208201905061035f600083018461033b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600181106103a5576103a4610365565b5b50565b60008190506103b682610394565b919050565b60006103c6826103a8565b9050919050565b6103d6816103bb565b82525050565b600082825260208201905092915050565b7f416d6f756e740000000000000000000000000000000000000000000000000000600082015250565b60006104236006836103dc565b915061042e826103ed565b602082019050919050565b600081519050919050565b60005b83811015610462578082015181840152602081019050610447565b60008484015250505050565b600061047982610439565b61048381856103dc565b9350610493818560208601610444565b61049c816101ac565b840191505092915050565b60006060820190506104bc60008301856103cd565b81810360208301526104cd81610416565b905081810360408301526104e1818461046e565b90509392505050565b600081519050919050565b600081905092915050565b600061050b826104ea565b61051581856104f5565b9350610525818560208601610444565b80840191505092915050565b600061053d8284610500565b915081905092915050565b7f6661696c656420746f20676574206163636f756e742062616c616e6365000000600082015250565b600061057e601d836103dc565b915061058982610548565b602082019050919050565b600060208201905081810360008301526105ad81610571565b9050919050565b6105bd81610331565b81146105c857600080fd5b50565b6000815190506105da816105b4565b92915050565b6000602082840312156105f6576105f5610198565b5b6000610604848285016105cb565b91505092915050565b7f62616c616e636500000000000000000000000000000000000000000000000000600082015250565b60006106436007836103dc565b915061064e8261060d565b602082019050919050565b6000604082019050818103600083015261067281610636565b9050610681602083018461033b565b9291505056fea2646970667358221220c3e34f0989dd6a37b0ef1efd133f9204e87676e4f623bd2ed7bdc6b7495c955464736f6c63430008150033","v":"0x6095","r":"0x9cd962349de5242d0c06a7497d9af10fff0093a2e0d89a84a510dedf542c98db","s":"0xbf35c832b9bb95aeea1dcef91fed916e8df4bb853fff7def884570019004aab","hash":"0x1eb22482ecccb5056cb8813539eae824649309b019c5fa4d211e0c1ef550ecdf"}]
|
||||
14
demos/algorand/txs/2_call_getAccountBalance/alloc.json
Normal file
14
demos/algorand/txs/2_call_getAccountBalance/alloc.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"0x6feaf11191837029e00915a6cd877dc334f6dce4": {
|
||||
"code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c82b4dbb14610030575b600080fd5b61004a600480360381019061004591906102e8565b610060565b604051610057919061034a565b60405180910390f35b600080600060ff73ffffffffffffffffffffffffffffffffffffffff166000856040516020016100919291906104a7565b6040516020818303038152906040526040516100ad9190610531565b6000604051808303816000865af19150503d80600081146100ea576040519150601f19603f3d011682016040523d82523d6000602084013e6100ef565b606091505b509150915081610134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012b90610594565b60405180910390fd5b60008180602001905181019061014a91906105e0565b90507fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b58160405161017b9190610659565b60405180910390a1809350505050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6101f5826101ac565b810181811067ffffffffffffffff82111715610214576102136101bd565b5b80604052505050565b600061022761018e565b905061023382826101ec565b919050565b600067ffffffffffffffff821115610253576102526101bd565b5b61025c826101ac565b9050602081019050919050565b82818337600083830152505050565b600061028b61028684610238565b61021d565b9050828152602081018484840111156102a7576102a66101a7565b5b6102b2848285610269565b509392505050565b600082601f8301126102cf576102ce6101a2565b5b81356102df848260208601610278565b91505092915050565b6000602082840312156102fe576102fd610198565b5b600082013567ffffffffffffffff81111561031c5761031b61019d565b5b610328848285016102ba565b91505092915050565b6000819050919050565b61034481610331565b82525050565b600060208201905061035f600083018461033b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600181106103a5576103a4610365565b5b50565b60008190506103b682610394565b919050565b60006103c6826103a8565b9050919050565b6103d6816103bb565b82525050565b600082825260208201905092915050565b7f416d6f756e740000000000000000000000000000000000000000000000000000600082015250565b60006104236006836103dc565b915061042e826103ed565b602082019050919050565b600081519050919050565b60005b83811015610462578082015181840152602081019050610447565b60008484015250505050565b600061047982610439565b61048381856103dc565b9350610493818560208601610444565b61049c816101ac565b840191505092915050565b60006060820190506104bc60008301856103cd565b81810360208301526104cd81610416565b905081810360408301526104e1818461046e565b90509392505050565b600081519050919050565b600081905092915050565b600061050b826104ea565b61051581856104f5565b9350610525818560208601610444565b80840191505092915050565b600061053d8284610500565b915081905092915050565b7f6661696c656420746f20676574206163636f756e742062616c616e6365000000600082015250565b600061057e601d836103dc565b915061058982610548565b602082019050919050565b600060208201905081810360008301526105ad81610571565b9050919050565b6105bd81610331565b81146105c857600080fd5b50565b6000815190506105da816105b4565b92915050565b6000602082840312156105f6576105f5610198565b5b6000610604848285016105cb565b91505092915050565b7f62616c616e636500000000000000000000000000000000000000000000000000600082015250565b60006106436007836103dc565b915061064e8261060d565b602082019050919050565b6000604082019050818103600083015261067281610636565b9050610681602083018461033b565b9291505056fea2646970667358221220c3e34f0989dd6a37b0ef1efd133f9204e87676e4f623bd2ed7bdc6b7495c955464736f6c63430008150033",
|
||||
"balance": "0x0",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0x7ea155883a46dccf117972cb1e438fe5ec1c353c": {
|
||||
"balance": "0xfff98817",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xc207a7021fbef833a19f3688a5e7a8cf1e331391": {
|
||||
"balance": "0xffff"
|
||||
}
|
||||
}
|
||||
12
demos/algorand/txs/2_call_getAccountBalance/env.json
Normal file
12
demos/algorand/txs/2_call_getAccountBalance/env.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"currentCoinbase": "0xc207a7021fbef833a19f3688a5e7a8cf1e331391",
|
||||
"currentDifficulty": "0x1",
|
||||
"currentGasLimit": "0x05f5e100",
|
||||
"currentBaseFee": "0x1",
|
||||
"currentNumber": "0x01",
|
||||
"currentTimestamp": "0x03e8",
|
||||
"previousHash": "0xe729de3fec21e30bea3d56adb01ed14bc107273c2775f9355afb10f594a10d9e",
|
||||
"blockHashes": {
|
||||
"0": "0xe729de3fec21e30bea3d56adb01ed14bc107273c2775f9355afb10f594a10d9e"
|
||||
}
|
||||
}
|
||||
12
demos/algorand/txs/2_call_getAccountBalance/txn.json
Normal file
12
demos/algorand/txs/2_call_getAccountBalance/txn.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"from": "0x7ea155883a46dccf117972cb1e438fe5ec1c353c",
|
||||
"to": "0x6feaf11191837029e00915a6cd877dc334f6dce4",
|
||||
"gas": "0xEFFFFF",
|
||||
"gasPrice": "0x1",
|
||||
"nonce": "0x1",
|
||||
"value": "0x0",
|
||||
"input": "0xc82b4dbb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a3733373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737375546454a324349000000000000",
|
||||
"r": "0x0",
|
||||
"s": "0x0",
|
||||
"v": "0x0"
|
||||
}
|
||||
1
demos/algorand/txs/2_call_getAccountBalance/txs.json
Normal file
1
demos/algorand/txs/2_call_getAccountBalance/txs.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
[{"type":"0x0","chainId":"0x3039","nonce":"0x1","to":"0x6feaf11191837029e00915a6cd877dc334f6dce4","gas":"0xefffff","gasPrice":"0x1","maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x0","input":"0xc82b4dbb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a3733373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737375546454a324349000000000000","v":"0x6096","r":"0x9e77098cdb2ca3193be26b0cf21b39a1596594c7b2b5daf5d39bea36a1ff4e42","s":"0x37a89f4cc4a32c3a5311d63a9c74b9839dc765e0c1c9c3ea26e8173d8dbe626f","hash":"0x7f7910dd079df505fcdb23d3856d7aae0500ce38659a2ff2d801ae8b55952022"}]
|
||||
59
demos/sign_txn/main.go
Normal file
59
demos/sign_txn/main.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"math/big"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
keystorePath := flag.String("keystore", "", "Keystore path")
|
||||
txnPath := flag.String("txn", "", "Unsigned transaction")
|
||||
chainIDArg := flag.String("chainid", "", "Chain ID")
|
||||
signer := flag.String("signer", "", "Signer")
|
||||
password := flag.String("password", "", "Password")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
ks := keystore.NewKeyStore(*keystorePath, keystore.StandardScryptN, keystore.StandardScryptP)
|
||||
|
||||
account, err := ks.Find(accounts.Account{Address: common.HexToAddress(*signer)})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
txnData, err := os.ReadFile(*txnPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var txn types.Transaction
|
||||
if err := txn.UnmarshalJSON(txnData); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
chainID, ok := new(big.Int).SetString(*chainIDArg, 10)
|
||||
if !ok {
|
||||
panic("invalid chain ID")
|
||||
}
|
||||
|
||||
signedTxn, err := ks.SignTxWithPassphrase(account, *password, &txn, chainID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
txs := []*types.Transaction{signedTxn}
|
||||
txsData, err := json.Marshal(txs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = os.WriteFile("txs.json", txsData, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
3
go.mod
3
go.mod
|
|
@ -80,6 +80,9 @@ require (
|
|||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
|
||||
github.com/DataDog/zstd v1.4.5 // indirect
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/algorand/avm-abi v0.2.0 // indirect
|
||||
github.com/algorand/go-algorand-sdk v1.24.0 // indirect
|
||||
github.com/algorand/go-codec/codec v1.1.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 // indirect
|
||||
|
|
|
|||
12
go.sum
12
go.sum
|
|
@ -63,6 +63,12 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/algorand/avm-abi v0.2.0 h1:bkjsG+BOEcxUcnGSALLosmltE0JZdg+ZisXKx0UDX2k=
|
||||
github.com/algorand/avm-abi v0.2.0/go.mod h1:+CgwM46dithy850bpTeHh9MC99zpn2Snirb3QTl2O/g=
|
||||
github.com/algorand/go-algorand-sdk v1.24.0 h1:mi8vqjXMC5nU87snq4vxHi+NgPR0thtZHRLA16FKZMM=
|
||||
github.com/algorand/go-algorand-sdk v1.24.0/go.mod h1:WEeJcctOHMzDFTgVJ6GT8BLUo9DbFTT47S+Kzx7ffXQ=
|
||||
github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA=
|
||||
github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
|
|
@ -559,6 +565,7 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt
|
|||
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
|
@ -600,6 +607,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
|
|
@ -653,6 +661,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
|||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
|
|
@ -694,6 +703,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
|
|
@ -771,6 +781,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
@ -850,6 +861,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
|||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ const (
|
|||
|
||||
BlobTxTargetBlobGasPerBlock = 3 * BlobTxBlobGasPerBlob // Target consumable blob gas for data blobs per block (for 1559-like pricing)
|
||||
MaxBlobGasPerBlock = 6 * BlobTxBlobGasPerBlob // Maximum consumable blob gas for data blobs per block
|
||||
|
||||
AlgorandPrecompileGas = 1000 // Gas price for the Algorand precompile.
|
||||
)
|
||||
|
||||
// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations
|
||||
|
|
|
|||
Loading…
Reference in a new issue