package genex import ( "context" "fmt" "math/big" "strings" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) // Settlement 合约 ABI(executeSwap 函数签名) const settlementABIJSON = `[{"name":"executeSwap","type":"function","inputs":[{"name":"tokenId","type":"uint256"},{"name":"buyer","type":"address"},{"name":"seller","type":"address"},{"name":"price","type":"uint256"},{"name":"stablecoin","type":"address"}],"outputs":[]}]` // SettlementContractAddress 默认 Settlement 合约地址(可通过配置覆盖) var SettlementContractAddress = common.HexToAddress("0x0000000000000000000000000000000000000004") // TxReceipt 交易回执 type TxReceipt struct { TxHash string `json:"txHash"` BlockNumber int64 `json:"blockNumber"` GasUsed uint64 `json:"gasUsed"` Status uint64 `json:"status"` // 1=success, 0=failed } // ExecuteSwap 构造+签名+广播券原子交换交易 func (c *Client) ExecuteSwap(params SwapParams, signer Signer) (*TxReceipt, error) { parsedABI, err := abi.JSON(strings.NewReader(settlementABIJSON)) if err != nil { return nil, fmt.Errorf("parse settlement ABI: %w", err) } calldata, err := parsedABI.Pack("executeSwap", params.TokenID, params.Buyer, params.Seller, params.Price, params.Stablecoin, ) if err != nil { return nil, fmt.Errorf("pack executeSwap: %w", err) } // 获取 nonce nonce, err := c.ethClient.PendingNonceAt(context.Background(), signer.GetAddress()) if err != nil { return nil, fmt.Errorf("get nonce: %w", err) } // 获取 gas price gasPrice, err := c.ethClient.SuggestGasPrice(context.Background()) if err != nil { return nil, fmt.Errorf("suggest gas price: %w", err) } // 构造交易 tx := types.NewTransaction( nonce, SettlementContractAddress, big.NewInt(0), uint64(300000), // gas limit gasPrice, calldata, ) // 签名 signedBytes, err := signer.SignTransaction(tx) if err != nil { return nil, fmt.Errorf("sign transaction: %w", err) } // 广播 var signedTx types.Transaction if err := signedTx.UnmarshalBinary(signedBytes); err != nil { return nil, fmt.Errorf("unmarshal signed tx: %w", err) } if err := c.ethClient.SendTransaction(context.Background(), &signedTx); err != nil { return nil, fmt.Errorf("send transaction: %w", err) } // 等待回执 receipt, err := c.ethClient.TransactionReceipt(context.Background(), signedTx.Hash()) if err != nil { return nil, fmt.Errorf("get receipt: %w", err) } return &TxReceipt{ TxHash: signedTx.Hash().Hex(), BlockNumber: receipt.BlockNumber.Int64(), GasUsed: receipt.GasUsed, Status: receipt.Status, }, nil }