Eth JSON-RPC API: Add EAM as contract creator (#9528)
This commit is contained in:
parent
98e534cc77
commit
7e7fff1dc5
@ -7,14 +7,12 @@ import (
|
||||
mathbig "math/big"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
gocrypto "github.com/filecoin-project/go-crypto"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v8/evm"
|
||||
init8 "github.com/filecoin-project/go-state-types/builtin/v8/init"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v8/eam"
|
||||
typescrypto "github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -60,21 +58,16 @@ type EthTxArgs struct {
|
||||
func NewEthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
var to *EthAddress
|
||||
params := msg.Params
|
||||
if msg.To == builtintypes.InitActorAddr {
|
||||
if msg.To == builtintypes.EthereumAddressManagerActorAddr {
|
||||
to = nil
|
||||
|
||||
var exec init8.ExecParams
|
||||
var create2 eam.Create2Params
|
||||
reader := bytes.NewReader(msg.Params)
|
||||
if err := exec.UnmarshalCBOR(reader); err != nil {
|
||||
if err := create2.UnmarshalCBOR(reader); err != nil {
|
||||
return EthTxArgs{}, err
|
||||
}
|
||||
|
||||
var evmParams evm.ConstructorParams
|
||||
reader1 := bytes.NewReader(exec.ConstructorParams)
|
||||
if err := evmParams.UnmarshalCBOR(reader1); err != nil {
|
||||
return EthTxArgs{}, err
|
||||
}
|
||||
params = evmParams.Bytecode
|
||||
params = create2.Initcode
|
||||
} else {
|
||||
addr, err := EthAddressFromFilecoinIDAddress(msg.To)
|
||||
if err != nil {
|
||||
@ -113,27 +106,19 @@ func (tx *EthTxArgs) ToSignedMessage() (*types.SignedMessage, error) {
|
||||
// TODO unify with applyEvmMsg
|
||||
|
||||
// this is a contract creation
|
||||
to = builtintypes.InitActorAddr
|
||||
to = builtintypes.EthereumAddressManagerActorAddr
|
||||
|
||||
constructorParams, err := actors.SerializeParams(&evm.ConstructorParams{
|
||||
Bytecode: tx.Input,
|
||||
var salt [32]byte
|
||||
binary.BigEndian.PutUint64(salt[:], uint64(tx.Nonce))
|
||||
|
||||
params2, err := actors.SerializeParams(&eam.Create2Params{
|
||||
Initcode: tx.Input,
|
||||
Salt: salt,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize constructor params: %w", err)
|
||||
}
|
||||
|
||||
evmActorCid, ok := actors.GetActorCodeID(actors.Version8, "evm")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to lookup evm actor code CID")
|
||||
}
|
||||
|
||||
params, err = actors.SerializeParams(&init8.ExecParams{
|
||||
CodeCID: evmActorCid,
|
||||
ConstructorParams: constructorParams,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize init actor exec params: %w", err)
|
||||
return nil, fmt.Errorf("failed to serialize Create2 params: %w", err)
|
||||
}
|
||||
params = params2
|
||||
} else {
|
||||
addr, err := tx.To.ToFilecoinAddress()
|
||||
if err != nil {
|
||||
@ -276,7 +261,7 @@ func (tx *EthTxArgs) Sender() (address.Address, error) {
|
||||
|
||||
func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
|
||||
if data[0] != 2 {
|
||||
return nil, xerrors.Errorf("not an EIP-1559 transaction: first byte is not 2")
|
||||
return nil, fmt.Errorf("not an EIP-1559 transaction: first byte is not 2")
|
||||
}
|
||||
|
||||
d, err := DecodeRLP(data[1:])
|
||||
@ -285,11 +270,11 @@ func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
|
||||
}
|
||||
decoded, ok := d.([]interface{})
|
||||
if !ok {
|
||||
return nil, xerrors.Errorf("not an EIP-1559 transaction: decoded data is not a list")
|
||||
return nil, fmt.Errorf("not an EIP-1559 transaction: decoded data is not a list")
|
||||
}
|
||||
|
||||
if len(decoded) != 9 && len(decoded) != 12 {
|
||||
return nil, xerrors.Errorf("not an EIP-1559 transaction: should have 6 or 9 elements in the list")
|
||||
return nil, fmt.Errorf("not an EIP-1559 transaction: should have 6 or 9 elements in the list")
|
||||
}
|
||||
|
||||
chainId, err := parseInt(decoded[0])
|
||||
@ -375,15 +360,15 @@ func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
|
||||
func ParseEthTxArgs(data []byte) (*EthTxArgs, error) {
|
||||
if data[0] > 0x7f {
|
||||
// legacy transaction
|
||||
return nil, xerrors.Errorf("legacy transaction is not supported")
|
||||
return nil, fmt.Errorf("legacy transaction is not supported")
|
||||
} else if data[0] == 1 {
|
||||
// EIP-2930
|
||||
return nil, xerrors.Errorf("EIP-2930 transaction is not supported")
|
||||
return nil, fmt.Errorf("EIP-2930 transaction is not supported")
|
||||
} else if data[0] == 2 {
|
||||
// EIP-1559
|
||||
return parseEip1559Tx(data)
|
||||
}
|
||||
return nil, xerrors.Errorf("unsupported transaction type")
|
||||
return nil, fmt.Errorf("unsupported transaction type")
|
||||
}
|
||||
|
||||
func padLeadingZeros(data []byte, length int) []byte {
|
||||
@ -432,18 +417,18 @@ func formatBigInt(val big.Int) ([]byte, error) {
|
||||
func parseInt(v interface{}) (int, error) {
|
||||
data, ok := v.([]byte)
|
||||
if !ok {
|
||||
return 0, xerrors.Errorf("cannot parse interface to int: input is not a byte array")
|
||||
return 0, fmt.Errorf("cannot parse interface to int: input is not a byte array")
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if len(data) > 8 {
|
||||
return 0, xerrors.Errorf("cannot parse interface to int: length is more than 8 bytes")
|
||||
return 0, fmt.Errorf("cannot parse interface to int: length is more than 8 bytes")
|
||||
}
|
||||
var value int64
|
||||
r := bytes.NewReader(append(make([]byte, 8-len(data)), data...))
|
||||
if err := binary.Read(r, binary.BigEndian, &value); err != nil {
|
||||
return 0, xerrors.Errorf("cannot parse interface to EthUint64: %w", err)
|
||||
return 0, fmt.Errorf("cannot parse interface to EthUint64: %w", err)
|
||||
}
|
||||
return int(value), nil
|
||||
}
|
||||
@ -451,7 +436,7 @@ func parseInt(v interface{}) (int, error) {
|
||||
func parseBigInt(v interface{}) (big.Int, error) {
|
||||
data, ok := v.([]byte)
|
||||
if !ok {
|
||||
return big.Zero(), xerrors.Errorf("cannot parse interface to big.Int: input is not a byte array")
|
||||
return big.Zero(), fmt.Errorf("cannot parse interface to big.Int: input is not a byte array")
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return big.Zero(), nil
|
||||
@ -464,7 +449,7 @@ func parseBigInt(v interface{}) (big.Int, error) {
|
||||
func parseBytes(v interface{}) ([]byte, error) {
|
||||
val, ok := v.([]byte)
|
||||
if !ok {
|
||||
return nil, xerrors.Errorf("cannot parse interface into bytes: input is not a byte array")
|
||||
return nil, fmt.Errorf("cannot parse interface into bytes: input is not a byte array")
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user