From 4ddbf6364fb69db33ec8a47dd553be176066be0b Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Tue, 24 Sep 2024 01:34:12 -0300 Subject: [PATCH 01/22] Feat: Add safe flag --- Makefile | 4 + bindings/GnosisSafe/GnosisSafe.go | 6777 +++++++++++++++++ .../ImmutableCreate2Factory.go | 985 +++ evm/generators.go | 595 +- examples/ownable-erc-721/OwnableERC721.go | 728 +- go.mod | 10 +- go.sum | 32 +- 7 files changed, 8931 insertions(+), 200 deletions(-) create mode 100644 bindings/GnosisSafe/GnosisSafe.go create mode 100644 bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go diff --git a/Makefile b/Makefile index 5e704c7..e787b17 100644 --- a/Makefile +++ b/Makefile @@ -16,3 +16,7 @@ examples/ownable-erc-721/OwnableERC721.go: rebuild ownable-erc-721: examples/ownable-erc-721/OwnableERC721.go go build ./examples/ownable-erc-721 + + + +token-sender: ./seer evm generate --package TokenSender --output ../../g7/protocol/bindings/TokenSender/TokenSender.go --hardhat ../../g7/protocol/web3/artifacts/contracts/faucet/TokenSender.sol/TokenSender.json --cli --struct TokenSender diff --git a/bindings/GnosisSafe/GnosisSafe.go b/bindings/GnosisSafe/GnosisSafe.go new file mode 100644 index 0000000..ec513c3 --- /dev/null +++ b/bindings/GnosisSafe/GnosisSafe.go @@ -0,0 +1,6777 @@ +// This file was generated by seer: https://github.com/moonstream-to/seer. +// seer version: 0.1.20 +// seer command: seer evm generate --package GnosisSafe --cli --struct GnosisSafe --output bindings/GnosisSafe/GnosisSafe.go +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package GnosisSafe + +import ( + "errors" + "math/big" + "strings" + + "context" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + // Reference imports to suppress errors if they are not otherwise used. + "encoding/hex" + "encoding/json" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// GnosisSafeMetaData contains all meta data concerning the GnosisSafe contract. +var GnosisSafeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AddedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"approvedHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ApproveHash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"masterCopy\",\"type\":\"address\"}],\"name\":\"ChangedMasterCopy\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"ChangedThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"DisabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"EnabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemovedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"SignMsg\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"addOwnerWithThreshold\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashToApprove\",\"type\":\"bytes32\"}],\"name\":\"approveHash\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"approvedHashes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_masterCopy\",\"type\":\"address\"}],\"name\":\"changeMasterCopy\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"changeThreshold\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contractModule\",\"name\":\"prevModule\",\"type\":\"address\"},{\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"disableModule\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"enableModule\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"encodeTransactionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"execTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModuleReturnData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"getMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getModules\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"start\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getModulesPaginated\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"array\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"next\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"getTransactionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isModuleEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"removeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"requiredTxGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"setFallbackHandler\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"paymentReceiver\",\"type\":\"address\"}],\"name\":\"setup\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"signMessage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"signedMessages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"swapOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506001600481905550615f5a80620000296000396000f3fe6080604052600436106101d85760003560e01c8063a3f4df7e11610102578063e009cfde11610095578063f08a032311610064578063f08a03231461156b578063f698da25146115bc578063f8dc5dd9146115e7578063ffa1ad7414611662576101d8565b8063e009cfde1461125d578063e318b52b146112ce578063e75235b81461135f578063e86637db1461138a576101d8565b8063c4ca3a9c116100d1578063c4ca3a9c14610ef2578063cc2f845214610fc3578063d4d9bdcd146110a6578063d8d11f78146110e1576101d8565b8063a3f4df7e14610c5b578063affed0e014610ceb578063b2494df314610d16578063b63e800d14610d82576101d8565b80635ae6bd371161017a5780637d832974116101495780637d83297414610aa95780637de7edef14610b1857806385a5affe14610b69578063a0e67e2b14610bef576101d8565b80635ae6bd3714610852578063610b5925146108a1578063694e80c3146108f25780636a7612021461092d576101d8565b80632d9ad53d116101b65780632d9ad53d146104e65780632f54bf6e1461054f578063468721a7146105b85780635229073f146106cf576101d8565b80630a1028c4146102825780630d582f131461035e57806320c13b0b146103b9575b60003411806101ea5750600080369050145b156101f457610280565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b9050600081549050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461027d57366000803760008036600080855af13d6000803e6000811415610278573d6000fd5b3d6000f35b50505b005b34801561028e57600080fd5b50610348600480360360208110156102a557600080fd5b81019080803590602001906401000000008111156102c257600080fd5b8201836020820111156102d457600080fd5b803590602001918460018302840111640100000000831117156102f657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506116f2565b6040518082815260200191505060405180910390f35b34801561036a57600080fd5b506103b76004803603604081101561038157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611829565b005b3480156103c557600080fd5b50610492600480360360408110156103dc57600080fd5b81019080803590602001906401000000008111156103f957600080fd5b82018360208201111561040b57600080fd5b8035906020019184600183028401116401000000008311171561042d57600080fd5b90919293919293908035906020019064010000000081111561044e57600080fd5b82018360208201111561046057600080fd5b8035906020019184600183028401116401000000008311171561048257600080fd5b9091929391929390505050611c73565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b3480156104f257600080fd5b506105356004803603602081101561050957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e09565b604051808215151515815260200191505060405180910390f35b34801561055b57600080fd5b5061059e6004803603602081101561057257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611edb565b604051808215151515815260200191505060405180910390f35b3480156105c457600080fd5b506106b5600480360360808110156105db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561062257600080fd5b82018360208201111561063457600080fd5b8035906020019184600183028401116401000000008311171561065657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611fad565b604051808215151515815260200191505060405180910390f35b3480156106db57600080fd5b506107cc600480360360808110156106f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561073957600080fd5b82018360208201111561074b57600080fd5b8035906020019184600183028401116401000000008311171561076d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050612176565b604051808315151515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108165780820151818401526020810190506107fb565b50505050905090810190601f1680156108435780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561085e57600080fd5b5061088b6004803603602081101561087557600080fd5b81019080803590602001909291905050506121ac565b6040518082815260200191505060405180910390f35b3480156108ad57600080fd5b506108f0600480360360208110156108c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121c4565b005b3480156108fe57600080fd5b5061092b6004803603602081101561091557600080fd5b81019080803590602001909291905050506125e8565b005b610a8f600480360361014081101561094457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561098b57600080fd5b82018360208201111561099d57600080fd5b803590602001918460018302840111640100000000831117156109bf57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610a4b57600080fd5b820183602082011115610a5d57600080fd5b80359060200191846001830284011164010000000083111715610a7f57600080fd5b9091929391929390505050612764565b604051808215151515815260200191505060405180910390f35b348015610ab557600080fd5b50610b0260048036036040811015610acc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506129ec565b6040518082815260200191505060405180910390f35b348015610b2457600080fd5b50610b6760048036036020811015610b3b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a11565b005b348015610b7557600080fd5b50610bed60048036036020811015610b8c57600080fd5b8101908080359060200190640100000000811115610ba957600080fd5b820183602082011115610bbb57600080fd5b80359060200191846001830284011164010000000083111715610bdd57600080fd5b9091929391929390505050612bc1565b005b348015610bfb57600080fd5b50610c04612ce1565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610c47578082015181840152602081019050610c2c565b505050509050019250505060405180910390f35b348015610c6757600080fd5b50610c70612e76565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610cb0578082015181840152602081019050610c95565b50505050905090810190601f168015610cdd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610cf757600080fd5b50610d00612eaf565b6040518082815260200191505060405180910390f35b348015610d2257600080fd5b50610d2b612eb5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d6e578082015181840152602081019050610d53565b505050509050019250505060405180910390f35b348015610d8e57600080fd5b50610ef06004803603610100811015610da657600080fd5b8101908080359060200190640100000000811115610dc357600080fd5b820183602082011115610dd557600080fd5b80359060200191846020830284011164010000000083111715610df757600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e4257600080fd5b820183602082011115610e5457600080fd5b80359060200191846001830284011164010000000083111715610e7657600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ece565b005b348015610efe57600080fd5b50610fad60048036036080811015610f1557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610f5c57600080fd5b820183602082011115610f6e57600080fd5b80359060200191846001830284011164010000000083111715610f9057600080fd5b9091929391929390803560ff1690602001909291905050506130c9565b6040518082815260200191505060405180910390f35b348015610fcf57600080fd5b5061101c60048036036040811015610fe657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613276565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b83811015611091578082015181840152602081019050611076565b50505050905001935050505060405180910390f35b3480156110b257600080fd5b506110df600480360360208110156110c957600080fd5b8101908080359060200190929190505050613455565b005b3480156110ed57600080fd5b50611247600480360361014081101561110557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561114c57600080fd5b82018360208201111561115e57600080fd5b8035906020019184600183028401116401000000008311171561118057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506135f4565b6040518082815260200191505060405180910390f35b34801561126957600080fd5b506112cc6004803603604081101561128057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061361f565b005b3480156112da57600080fd5b5061135d600480360360608110156112f157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613a25565b005b34801561136b57600080fd5b506113746140ea565b6040518082815260200191505060405180910390f35b34801561139657600080fd5b506114f060048036036101408110156113ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156113f557600080fd5b82018360208201111561140757600080fd5b8035906020019184600183028401116401000000008311171561142957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506140f4565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611530578082015181840152602081019050611515565b50505050905090810190601f16801561155d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561157757600080fd5b506115ba6004803603602081101561158e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614308565b005b3480156115c857600080fd5b506115d1614398565b6040518082815260200191505060405180910390f35b3480156115f357600080fd5b506116606004803603606081101561160a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061439e565b005b34801561166e57600080fd5b50611677614829565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156116b757808201518184015260208101905061169c565b50505050905090810190601f1680156116e45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60001b83805190602001206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050601960f81b600160f81b6006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156119175750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611a8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611c6f57611c6e816125e8565b5b5050565b600080611cc386868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506116f2565b90506000848490501415611d6057600060076000838152602001908152602001600020541415611d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f48617368206e6f7420617070726f76656400000000000000000000000000000081525060200191505060405180910390fd5b611df6565b611df58187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000614862565b5b6320c13b0b60e01b915050949350505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff1614158015611ed45750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611fa65750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156120785750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b6120cd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180615e736030913960400191505060405180910390fd5b6120da858585855a615190565b9050801561212a573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a261216e565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000606061218686868686611fad565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156122b25750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4d6f64756c652068617320616c7265616479206265656e20616464656400000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461266c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b6003548111156126c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615d166023913960400191505060405180910390fd5b6001811015612721576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615dec6024913960400191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b60008060606127c18f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e8e8e8e8e6005546140f4565b905060056000815480929190600101919050555080805190602001209150612830828287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001614862565b506101f46128586109c48b01603f60408d028161284957fe5b0461520290919063ffffffff16565b015a10156128b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615efc602a913960400191505060405180910390fd5b60005a905061291a8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d1461290f578e612915565b6109c45a035b615190565b925061292f5a8261521c90919063ffffffff16565b90506000809050600089111561294f5761294c828b8b8b8b61523c565b90505b8315612999577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8382604051808381526020018281526020019250505060405180910390a16129d9565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238382604051808381526020018281526020019250505060405180910390a15b5050509c9b505050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612b1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615c826024913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b881604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b6000612c9483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506116f2565b905060016007600083815260200190815260200160002081905550807fe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e460405160405180910390a2505050565b606080600354604051908082528060200260200182016040528015612d155781602001602082028038833980820191505090505b5090506000809050600060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e6d5780838381518110612dc457fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612d83565b82935050505090565b6040518060400160405280600b81526020017f476e6f736973205361666500000000000000000000000000000000000000000081525081565b60055481565b606080612ec46001600a613276565b5090508091505090565b6000801b60065414612f48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f446f6d61696e20536570617261746f7220616c7265616479207365742100000081525060200191505060405180910390fd5b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960001b30604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051602081830303815290604052805190602001206006819055506130178a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505089615408565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146130555761305484615861565b5b6130a38787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615890565b60008211156130bd576130bb8260006001868561523c565b505b50505050505050505050565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461314f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b60005a90506131a5878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615190565b6131ae57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561323b578082015181840152602081019050613220565b50505050905090810190601f1680156132685780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60606000826040519080825280602002602001820160405280156132a95781602001602082028038833980820191505090505b50915060008090506000600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156133805750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561338b57508482105b15613446578084838151811061339d57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613316565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f6e6c79206f776e6572732063616e20617070726f766520612068617368000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006136088b8b8b8b8b8b8b8b8b8b6140f4565b8051906020012090509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146136a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561370d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615cee6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613aa9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613b135750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613b85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613c86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613cf05750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613d62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615d906026913960400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8c8c8c805190602001208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561418457fe5b60ff1681526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461438c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b61439581615861565b50565b60065481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b806001600354031015614480576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180615d396035913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156144ea5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61455c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461463f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615d906026913960400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461482457614823816125e8565b5b505050565b6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60006004549050600081116148df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f5468726573686f6c64206e6565647320746f20626520646566696e656421000081525060200191505060405180910390fd5b6148f3604182615aaa90919063ffffffff16565b83511015614969576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5369676e617475726573206461746120746f6f2073686f72740000000000000081525060200191505060405180910390fd5b600080905060008060008060008090505b868110156151835761498c8982615ae4565b80945081955082965050505060008460ff161415614d21578260001c94506149be604188615aaa90919063ffffffff16565b8260001c1015614a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180615e106037913960400191505060405180910390fd5b8851614a3260208460001c615b1390919063ffffffff16565b1115614a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180615ea36037913960400191505060405180910390fd5b60006020838b01015190508951614abf82614ab160208760001c615b1390919063ffffffff16565b615b1390919063ffffffff16565b1115614b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180615db66036913960400191505060405180910390fd5b60606020848c010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8e846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015614bb8578082015181840152602081019050614b9d565b50505050905090810190601f168015614be55780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015614c1e578082015181840152602081019050614c03565b50505050905090810190601f168015614c4b5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015614c6a57600080fd5b505afa158015614c7e573d6000803e3d6000fd5b505050506040513d6020811015614c9457600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614614d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615ccb6023913960400191505060405180910390fd5b5050615001565b60018460ff161415614eca578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480614dbe57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d81526020019081526020016000205414155b614e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4861736820686173206e6f74206265656e20617070726f76656400000000000081525060200191505060405180910390fd5b878015614e6957508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15614ec5576000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020819055505b615000565b601e8460ff161115614f955760018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015614f84573d6000803e3d6000fd5b505050602060405103519450614fff565b60018b85858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015614ff2573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156150c85750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156151015750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b615173576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f496e76616c6964206f776e65722070726f76696465640000000000000000000081525060200191505060405180910390fd5b849550808060010191505061497a565b5050505050505050505050565b600080600181111561519e57fe5b8360018111156151aa57fe5b14156151c3576151bc86868685615b32565b90506151f9565b6001808111156151cf57fe5b8360018111156151db57fe5b14156151f3576151ec868584615b4b565b90506151f8565b600090505b5b95945050505050565b6000818310156152125781615214565b825b905092915050565b60008282111561522b57600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615279578261527b565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615376576152e53a86106152c2573a6152c4565b855b6152d7888a615b1390919063ffffffff16565b615aaa90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615eda6022913960400191505060405180910390fd5b6153fe565b61539b8561538d888a615b1390919063ffffffff16565b615aaa90919063ffffffff16565b91506153a8848284615b62565b6153fd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615d6e6022913960400191505060405180910390fd5b5b5095945050505050565b600060045414615480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f776e657273206861766520616c7265616479206265656e207365747570000081525060200191505060405180910390fd5b81518111156154da576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615d166023913960400191505060405180910390fd5b6001811015615534576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615dec6024913960400191505060405180910390fd5b60006001905060008090505b83518110156157cd57600084828151811061555757fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156155cb5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61563d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461573e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4475706c6963617465206f776e657220616464726573732070726f766964656481525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615540565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615975576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615ca66025913960400191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615aa657615a3382825a615b4b565b615aa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f436f756c64206e6f742066696e69736820696e697469616c697a6174696f6e0081525060200191505060405180910390fd5b5b5050565b600080831415615abd5760009050615ade565b6000828402905082848281615ace57fe5b0414615ad957600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015615b2857600080fd5b8091505092915050565b6000806000845160208601878987f19050949350505050565b60008060008451602086018786f490509392505050565b600060608383604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808251602084016000896127105a03f16040513d81016040523d6000823e3d60008114615c645760208114615c6c5760009450615c76565b829450615c76565b8151158315171594505b50505050939250505056fe496e76616c6964206d617374657220636f707920616464726573732070726f76696465644d6f64756c6573206861766520616c7265616479206265656e20696e697469616c697a6564496e76616c696420636f6e7472616374207369676e61747572652070726f7669646564496e76616c696420707265764d6f64756c652c206d6f64756c6520706169722070726f76696465645468726573686f6c642063616e6e6f7420657863656564206f776e657220636f756e744e6577206f776e657220636f756e74206e6565647320746f206265206c6172676572207468616e206e6577207468726573686f6c64436f756c64206e6f74207061792067617320636f737473207769746820746f6b656e496e76616c696420707265764f776e65722c206f776e657220706169722070726f7669646564496e76616c696420636f6e7472616374207369676e6174757265206c6f636174696f6e3a2064617461206e6f7420636f6d706c6574655468726573686f6c64206e6565647320746f2062652067726561746572207468616e2030496e76616c696420636f6e7472616374207369676e6174757265206c6f636174696f6e3a20696e736964652073746174696320706172744d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e74726163744d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d20616e20656e61626c6564206d6f64756c65496e76616c696420636f6e7472616374207369676e6174757265206c6f636174696f6e3a206c656e677468206e6f742070726573656e74436f756c64206e6f74207061792067617320636f73747320776974682065746865724e6f7420656e6f7567682067617320746f20657865637574652073616665207472616e73616374696f6ea265627a7a72315820da2029b344faa0acf527c9aacdbb26d18ce3a0599d09b320dfe387081b8e392264736f6c63430005110032", +} + +// GnosisSafeABI is the input ABI used to generate the binding from. +// Deprecated: Use GnosisSafeMetaData.ABI instead. +var GnosisSafeABI = GnosisSafeMetaData.ABI + +// GnosisSafeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GnosisSafeMetaData.Bin instead. +var GnosisSafeBin = GnosisSafeMetaData.Bin + +// DeployGnosisSafe deploys a new Ethereum contract, binding an instance of GnosisSafe to it. +func DeployGnosisSafe(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GnosisSafe, error) { + parsed, err := GnosisSafeMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GnosisSafeBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GnosisSafe{GnosisSafeCaller: GnosisSafeCaller{contract: contract}, GnosisSafeTransactor: GnosisSafeTransactor{contract: contract}, GnosisSafeFilterer: GnosisSafeFilterer{contract: contract}}, nil +} + +// GnosisSafe is an auto generated Go binding around an Ethereum contract. +type GnosisSafe struct { + GnosisSafeCaller // Read-only binding to the contract + GnosisSafeTransactor // Write-only binding to the contract + GnosisSafeFilterer // Log filterer for contract events +} + +// GnosisSafeCaller is an auto generated read-only Go binding around an Ethereum contract. +type GnosisSafeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GnosisSafeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GnosisSafeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GnosisSafeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GnosisSafeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GnosisSafeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GnosisSafeSession struct { + Contract *GnosisSafe // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GnosisSafeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GnosisSafeCallerSession struct { + Contract *GnosisSafeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// GnosisSafeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GnosisSafeTransactorSession struct { + Contract *GnosisSafeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GnosisSafeRaw is an auto generated low-level Go binding around an Ethereum contract. +type GnosisSafeRaw struct { + Contract *GnosisSafe // Generic contract binding to access the raw methods on +} + +// GnosisSafeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GnosisSafeCallerRaw struct { + Contract *GnosisSafeCaller // Generic read-only contract binding to access the raw methods on +} + +// GnosisSafeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GnosisSafeTransactorRaw struct { + Contract *GnosisSafeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewGnosisSafe creates a new instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafe(address common.Address, backend bind.ContractBackend) (*GnosisSafe, error) { + contract, err := bindGnosisSafe(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &GnosisSafe{GnosisSafeCaller: GnosisSafeCaller{contract: contract}, GnosisSafeTransactor: GnosisSafeTransactor{contract: contract}, GnosisSafeFilterer: GnosisSafeFilterer{contract: contract}}, nil +} + +// NewGnosisSafeCaller creates a new read-only instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafeCaller(address common.Address, caller bind.ContractCaller) (*GnosisSafeCaller, error) { + contract, err := bindGnosisSafe(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GnosisSafeCaller{contract: contract}, nil +} + +// NewGnosisSafeTransactor creates a new write-only instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafeTransactor(address common.Address, transactor bind.ContractTransactor) (*GnosisSafeTransactor, error) { + contract, err := bindGnosisSafe(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GnosisSafeTransactor{contract: contract}, nil +} + +// NewGnosisSafeFilterer creates a new log filterer instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafeFilterer(address common.Address, filterer bind.ContractFilterer) (*GnosisSafeFilterer, error) { + contract, err := bindGnosisSafe(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &GnosisSafeFilterer{contract: contract}, nil +} + +// bindGnosisSafe binds a generic wrapper to an already deployed contract. +func bindGnosisSafe(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := GnosisSafeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GnosisSafe *GnosisSafeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GnosisSafe.Contract.GnosisSafeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GnosisSafe *GnosisSafeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GnosisSafe.Contract.GnosisSafeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GnosisSafe *GnosisSafeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GnosisSafe.Contract.GnosisSafeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GnosisSafe *GnosisSafeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GnosisSafe.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GnosisSafe *GnosisSafeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GnosisSafe.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GnosisSafe *GnosisSafeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GnosisSafe.Contract.contract.Transact(opts, method, params...) +} + +// NAME is a free data retrieval call binding the contract method 0xa3f4df7e. +// +// Solidity: function NAME() view returns(string) +func (_GnosisSafe *GnosisSafeCaller) NAME(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "NAME") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// NAME is a free data retrieval call binding the contract method 0xa3f4df7e. +// +// Solidity: function NAME() view returns(string) +func (_GnosisSafe *GnosisSafeSession) NAME() (string, error) { + return _GnosisSafe.Contract.NAME(&_GnosisSafe.CallOpts) +} + +// NAME is a free data retrieval call binding the contract method 0xa3f4df7e. +// +// Solidity: function NAME() view returns(string) +func (_GnosisSafe *GnosisSafeCallerSession) NAME() (string, error) { + return _GnosisSafe.Contract.NAME(&_GnosisSafe.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_GnosisSafe *GnosisSafeCaller) VERSION(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_GnosisSafe *GnosisSafeSession) VERSION() (string, error) { + return _GnosisSafe.Contract.VERSION(&_GnosisSafe.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_GnosisSafe *GnosisSafeCallerSession) VERSION() (string, error) { + return _GnosisSafe.Contract.VERSION(&_GnosisSafe.CallOpts) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) ApprovedHashes(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "approvedHashes", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.ApprovedHashes(&_GnosisSafe.CallOpts, arg0, arg1) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.ApprovedHashes(&_GnosisSafe.CallOpts, arg0, arg1) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_GnosisSafe *GnosisSafeCaller) DomainSeparator(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "domainSeparator") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_GnosisSafe *GnosisSafeSession) DomainSeparator() ([32]byte, error) { + return _GnosisSafe.Contract.DomainSeparator(&_GnosisSafe.CallOpts) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_GnosisSafe *GnosisSafeCallerSession) DomainSeparator() ([32]byte, error) { + return _GnosisSafe.Contract.DomainSeparator(&_GnosisSafe.CallOpts) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_GnosisSafe *GnosisSafeCaller) EncodeTransactionData(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "encodeTransactionData", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_GnosisSafe *GnosisSafeSession) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _GnosisSafe.Contract.EncodeTransactionData(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_GnosisSafe *GnosisSafeCallerSession) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _GnosisSafe.Contract.EncodeTransactionData(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x0a1028c4. +// +// Solidity: function getMessageHash(bytes message) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCaller) GetMessageHash(opts *bind.CallOpts, message []byte) ([32]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getMessageHash", message) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x0a1028c4. +// +// Solidity: function getMessageHash(bytes message) view returns(bytes32) +func (_GnosisSafe *GnosisSafeSession) GetMessageHash(message []byte) ([32]byte, error) { + return _GnosisSafe.Contract.GetMessageHash(&_GnosisSafe.CallOpts, message) +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x0a1028c4. +// +// Solidity: function getMessageHash(bytes message) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCallerSession) GetMessageHash(message []byte) ([32]byte, error) { + return _GnosisSafe.Contract.GetMessageHash(&_GnosisSafe.CallOpts, message) +} + +// GetModules is a free data retrieval call binding the contract method 0xb2494df3. +// +// Solidity: function getModules() view returns(address[]) +func (_GnosisSafe *GnosisSafeCaller) GetModules(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getModules") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetModules is a free data retrieval call binding the contract method 0xb2494df3. +// +// Solidity: function getModules() view returns(address[]) +func (_GnosisSafe *GnosisSafeSession) GetModules() ([]common.Address, error) { + return _GnosisSafe.Contract.GetModules(&_GnosisSafe.CallOpts) +} + +// GetModules is a free data retrieval call binding the contract method 0xb2494df3. +// +// Solidity: function getModules() view returns(address[]) +func (_GnosisSafe *GnosisSafeCallerSession) GetModules() ([]common.Address, error) { + return _GnosisSafe.Contract.GetModules(&_GnosisSafe.CallOpts) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_GnosisSafe *GnosisSafeCaller) GetModulesPaginated(opts *bind.CallOpts, start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getModulesPaginated", start, pageSize) + + outstruct := new(struct { + Array []common.Address + Next common.Address + }) + if err != nil { + return *outstruct, err + } + + outstruct.Array = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.Next = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_GnosisSafe *GnosisSafeSession) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _GnosisSafe.Contract.GetModulesPaginated(&_GnosisSafe.CallOpts, start, pageSize) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_GnosisSafe *GnosisSafeCallerSession) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _GnosisSafe.Contract.GetModulesPaginated(&_GnosisSafe.CallOpts, start, pageSize) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_GnosisSafe *GnosisSafeCaller) GetOwners(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getOwners") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_GnosisSafe *GnosisSafeSession) GetOwners() ([]common.Address, error) { + return _GnosisSafe.Contract.GetOwners(&_GnosisSafe.CallOpts) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_GnosisSafe *GnosisSafeCallerSession) GetOwners() ([]common.Address, error) { + return _GnosisSafe.Contract.GetOwners(&_GnosisSafe.CallOpts) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) GetThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) GetThreshold() (*big.Int, error) { + return _GnosisSafe.Contract.GetThreshold(&_GnosisSafe.CallOpts) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) GetThreshold() (*big.Int, error) { + return _GnosisSafe.Contract.GetThreshold(&_GnosisSafe.CallOpts) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCaller) GetTransactionHash(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getTransactionHash", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_GnosisSafe *GnosisSafeSession) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _GnosisSafe.Contract.GetTransactionHash(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCallerSession) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _GnosisSafe.Contract.GetTransactionHash(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_GnosisSafe *GnosisSafeCaller) IsModuleEnabled(opts *bind.CallOpts, module common.Address) (bool, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "isModuleEnabled", module) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_GnosisSafe *GnosisSafeSession) IsModuleEnabled(module common.Address) (bool, error) { + return _GnosisSafe.Contract.IsModuleEnabled(&_GnosisSafe.CallOpts, module) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_GnosisSafe *GnosisSafeCallerSession) IsModuleEnabled(module common.Address) (bool, error) { + return _GnosisSafe.Contract.IsModuleEnabled(&_GnosisSafe.CallOpts, module) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_GnosisSafe *GnosisSafeCaller) IsOwner(opts *bind.CallOpts, owner common.Address) (bool, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "isOwner", owner) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_GnosisSafe *GnosisSafeSession) IsOwner(owner common.Address) (bool, error) { + return _GnosisSafe.Contract.IsOwner(&_GnosisSafe.CallOpts, owner) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_GnosisSafe *GnosisSafeCallerSession) IsOwner(owner common.Address) (bool, error) { + return _GnosisSafe.Contract.IsOwner(&_GnosisSafe.CallOpts, owner) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) Nonce(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "nonce") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) Nonce() (*big.Int, error) { + return _GnosisSafe.Contract.Nonce(&_GnosisSafe.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) Nonce() (*big.Int, error) { + return _GnosisSafe.Contract.Nonce(&_GnosisSafe.CallOpts) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) SignedMessages(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "signedMessages", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.SignedMessages(&_GnosisSafe.CallOpts, arg0) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.SignedMessages(&_GnosisSafe.CallOpts, arg0) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactor) AddOwnerWithThreshold(opts *bind.TransactOpts, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "addOwnerWithThreshold", owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeSession) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.AddOwnerWithThreshold(&_GnosisSafe.TransactOpts, owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.AddOwnerWithThreshold(&_GnosisSafe.TransactOpts, owner, _threshold) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_GnosisSafe *GnosisSafeTransactor) ApproveHash(opts *bind.TransactOpts, hashToApprove [32]byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "approveHash", hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_GnosisSafe *GnosisSafeSession) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ApproveHash(&_GnosisSafe.TransactOpts, hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ApproveHash(&_GnosisSafe.TransactOpts, hashToApprove) +} + +// ChangeMasterCopy is a paid mutator transaction binding the contract method 0x7de7edef. +// +// Solidity: function changeMasterCopy(address _masterCopy) returns() +func (_GnosisSafe *GnosisSafeTransactor) ChangeMasterCopy(opts *bind.TransactOpts, _masterCopy common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "changeMasterCopy", _masterCopy) +} + +// ChangeMasterCopy is a paid mutator transaction binding the contract method 0x7de7edef. +// +// Solidity: function changeMasterCopy(address _masterCopy) returns() +func (_GnosisSafe *GnosisSafeSession) ChangeMasterCopy(_masterCopy common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeMasterCopy(&_GnosisSafe.TransactOpts, _masterCopy) +} + +// ChangeMasterCopy is a paid mutator transaction binding the contract method 0x7de7edef. +// +// Solidity: function changeMasterCopy(address _masterCopy) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) ChangeMasterCopy(_masterCopy common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeMasterCopy(&_GnosisSafe.TransactOpts, _masterCopy) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactor) ChangeThreshold(opts *bind.TransactOpts, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "changeThreshold", _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeSession) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeThreshold(&_GnosisSafe.TransactOpts, _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeThreshold(&_GnosisSafe.TransactOpts, _threshold) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_GnosisSafe *GnosisSafeTransactor) DisableModule(opts *bind.TransactOpts, prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "disableModule", prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_GnosisSafe *GnosisSafeSession) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.DisableModule(&_GnosisSafe.TransactOpts, prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.DisableModule(&_GnosisSafe.TransactOpts, prevModule, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_GnosisSafe *GnosisSafeTransactor) EnableModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "enableModule", module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_GnosisSafe *GnosisSafeSession) EnableModule(module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.EnableModule(&_GnosisSafe.TransactOpts, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) EnableModule(module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.EnableModule(&_GnosisSafe.TransactOpts, module) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_GnosisSafe *GnosisSafeTransactor) ExecTransaction(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "execTransaction", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_GnosisSafe *GnosisSafeSession) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransaction(&_GnosisSafe.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_GnosisSafe *GnosisSafeTransactorSession) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransaction(&_GnosisSafe.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_GnosisSafe *GnosisSafeTransactor) ExecTransactionFromModule(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "execTransactionFromModule", to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_GnosisSafe *GnosisSafeSession) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModule(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_GnosisSafe *GnosisSafeTransactorSession) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModule(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_GnosisSafe *GnosisSafeTransactor) ExecTransactionFromModuleReturnData(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "execTransactionFromModuleReturnData", to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_GnosisSafe *GnosisSafeSession) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModuleReturnData(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_GnosisSafe *GnosisSafeTransactorSession) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModuleReturnData(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// IsValidSignature is a paid mutator transaction binding the contract method 0x20c13b0b. +// +// Solidity: function isValidSignature(bytes _data, bytes _signature) returns(bytes4) +func (_GnosisSafe *GnosisSafeTransactor) IsValidSignature(opts *bind.TransactOpts, _data []byte, _signature []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "isValidSignature", _data, _signature) +} + +// IsValidSignature is a paid mutator transaction binding the contract method 0x20c13b0b. +// +// Solidity: function isValidSignature(bytes _data, bytes _signature) returns(bytes4) +func (_GnosisSafe *GnosisSafeSession) IsValidSignature(_data []byte, _signature []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.IsValidSignature(&_GnosisSafe.TransactOpts, _data, _signature) +} + +// IsValidSignature is a paid mutator transaction binding the contract method 0x20c13b0b. +// +// Solidity: function isValidSignature(bytes _data, bytes _signature) returns(bytes4) +func (_GnosisSafe *GnosisSafeTransactorSession) IsValidSignature(_data []byte, _signature []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.IsValidSignature(&_GnosisSafe.TransactOpts, _data, _signature) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactor) RemoveOwner(opts *bind.TransactOpts, prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "removeOwner", prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeSession) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.RemoveOwner(&_GnosisSafe.TransactOpts, prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.RemoveOwner(&_GnosisSafe.TransactOpts, prevOwner, owner, _threshold) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_GnosisSafe *GnosisSafeTransactor) RequiredTxGas(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "requiredTxGas", to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_GnosisSafe *GnosisSafeSession) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.RequiredTxGas(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_GnosisSafe *GnosisSafeTransactorSession) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.RequiredTxGas(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_GnosisSafe *GnosisSafeTransactor) SetFallbackHandler(opts *bind.TransactOpts, handler common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "setFallbackHandler", handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_GnosisSafe *GnosisSafeSession) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SetFallbackHandler(&_GnosisSafe.TransactOpts, handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SetFallbackHandler(&_GnosisSafe.TransactOpts, handler) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_GnosisSafe *GnosisSafeTransactor) Setup(opts *bind.TransactOpts, _owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "setup", _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_GnosisSafe *GnosisSafeSession) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.Setup(&_GnosisSafe.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.Setup(&_GnosisSafe.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// SignMessage is a paid mutator transaction binding the contract method 0x85a5affe. +// +// Solidity: function signMessage(bytes _data) returns() +func (_GnosisSafe *GnosisSafeTransactor) SignMessage(opts *bind.TransactOpts, _data []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "signMessage", _data) +} + +// SignMessage is a paid mutator transaction binding the contract method 0x85a5affe. +// +// Solidity: function signMessage(bytes _data) returns() +func (_GnosisSafe *GnosisSafeSession) SignMessage(_data []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.SignMessage(&_GnosisSafe.TransactOpts, _data) +} + +// SignMessage is a paid mutator transaction binding the contract method 0x85a5affe. +// +// Solidity: function signMessage(bytes _data) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) SignMessage(_data []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.SignMessage(&_GnosisSafe.TransactOpts, _data) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_GnosisSafe *GnosisSafeTransactor) SwapOwner(opts *bind.TransactOpts, prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "swapOwner", prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_GnosisSafe *GnosisSafeSession) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SwapOwner(&_GnosisSafe.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SwapOwner(&_GnosisSafe.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_GnosisSafe *GnosisSafeTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_GnosisSafe *GnosisSafeSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.Fallback(&_GnosisSafe.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_GnosisSafe *GnosisSafeTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.Fallback(&_GnosisSafe.TransactOpts, calldata) +} + +// GnosisSafeAddedOwnerIterator is returned from FilterAddedOwner and is used to iterate over the raw logs and unpacked data for AddedOwner events raised by the GnosisSafe contract. +type GnosisSafeAddedOwnerIterator struct { + Event *GnosisSafeAddedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeAddedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeAddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeAddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeAddedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeAddedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeAddedOwner represents a AddedOwner event raised by the GnosisSafe contract. +type GnosisSafeAddedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddedOwner is a free log retrieval operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) FilterAddedOwner(opts *bind.FilterOpts) (*GnosisSafeAddedOwnerIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return &GnosisSafeAddedOwnerIterator{contract: _GnosisSafe.contract, event: "AddedOwner", logs: logs, sub: sub}, nil +} + +// WatchAddedOwner is a free log subscription operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) WatchAddedOwner(opts *bind.WatchOpts, sink chan<- *GnosisSafeAddedOwner) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeAddedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAddedOwner is a log parse operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) ParseAddedOwner(log types.Log) (*GnosisSafeAddedOwner, error) { + event := new(GnosisSafeAddedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeApproveHashIterator is returned from FilterApproveHash and is used to iterate over the raw logs and unpacked data for ApproveHash events raised by the GnosisSafe contract. +type GnosisSafeApproveHashIterator struct { + Event *GnosisSafeApproveHash // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeApproveHashIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeApproveHashIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeApproveHashIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeApproveHash represents a ApproveHash event raised by the GnosisSafe contract. +type GnosisSafeApproveHash struct { + ApprovedHash [32]byte + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproveHash is a free log retrieval operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_GnosisSafe *GnosisSafeFilterer) FilterApproveHash(opts *bind.FilterOpts, approvedHash [][32]byte, owner []common.Address) (*GnosisSafeApproveHashIterator, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return &GnosisSafeApproveHashIterator{contract: _GnosisSafe.contract, event: "ApproveHash", logs: logs, sub: sub}, nil +} + +// WatchApproveHash is a free log subscription operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_GnosisSafe *GnosisSafeFilterer) WatchApproveHash(opts *bind.WatchOpts, sink chan<- *GnosisSafeApproveHash, approvedHash [][32]byte, owner []common.Address) (event.Subscription, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeApproveHash) + if err := _GnosisSafe.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproveHash is a log parse operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_GnosisSafe *GnosisSafeFilterer) ParseApproveHash(log types.Log) (*GnosisSafeApproveHash, error) { + event := new(GnosisSafeApproveHash) + if err := _GnosisSafe.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeChangedMasterCopyIterator is returned from FilterChangedMasterCopy and is used to iterate over the raw logs and unpacked data for ChangedMasterCopy events raised by the GnosisSafe contract. +type GnosisSafeChangedMasterCopyIterator struct { + Event *GnosisSafeChangedMasterCopy // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeChangedMasterCopyIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedMasterCopy) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedMasterCopy) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeChangedMasterCopyIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeChangedMasterCopyIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeChangedMasterCopy represents a ChangedMasterCopy event raised by the GnosisSafe contract. +type GnosisSafeChangedMasterCopy struct { + MasterCopy common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedMasterCopy is a free log retrieval operation binding the contract event 0x75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b8. +// +// Solidity: event ChangedMasterCopy(address masterCopy) +func (_GnosisSafe *GnosisSafeFilterer) FilterChangedMasterCopy(opts *bind.FilterOpts) (*GnosisSafeChangedMasterCopyIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ChangedMasterCopy") + if err != nil { + return nil, err + } + return &GnosisSafeChangedMasterCopyIterator{contract: _GnosisSafe.contract, event: "ChangedMasterCopy", logs: logs, sub: sub}, nil +} + +// WatchChangedMasterCopy is a free log subscription operation binding the contract event 0x75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b8. +// +// Solidity: event ChangedMasterCopy(address masterCopy) +func (_GnosisSafe *GnosisSafeFilterer) WatchChangedMasterCopy(opts *bind.WatchOpts, sink chan<- *GnosisSafeChangedMasterCopy) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ChangedMasterCopy") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeChangedMasterCopy) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedMasterCopy", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedMasterCopy is a log parse operation binding the contract event 0x75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b8. +// +// Solidity: event ChangedMasterCopy(address masterCopy) +func (_GnosisSafe *GnosisSafeFilterer) ParseChangedMasterCopy(log types.Log) (*GnosisSafeChangedMasterCopy, error) { + event := new(GnosisSafeChangedMasterCopy) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedMasterCopy", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeChangedThresholdIterator is returned from FilterChangedThreshold and is used to iterate over the raw logs and unpacked data for ChangedThreshold events raised by the GnosisSafe contract. +type GnosisSafeChangedThresholdIterator struct { + Event *GnosisSafeChangedThreshold // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeChangedThresholdIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeChangedThresholdIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeChangedThresholdIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeChangedThreshold represents a ChangedThreshold event raised by the GnosisSafe contract. +type GnosisSafeChangedThreshold struct { + Threshold *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedThreshold is a free log retrieval operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_GnosisSafe *GnosisSafeFilterer) FilterChangedThreshold(opts *bind.FilterOpts) (*GnosisSafeChangedThresholdIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return &GnosisSafeChangedThresholdIterator{contract: _GnosisSafe.contract, event: "ChangedThreshold", logs: logs, sub: sub}, nil +} + +// WatchChangedThreshold is a free log subscription operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_GnosisSafe *GnosisSafeFilterer) WatchChangedThreshold(opts *bind.WatchOpts, sink chan<- *GnosisSafeChangedThreshold) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeChangedThreshold) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedThreshold is a log parse operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_GnosisSafe *GnosisSafeFilterer) ParseChangedThreshold(log types.Log) (*GnosisSafeChangedThreshold, error) { + event := new(GnosisSafeChangedThreshold) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeDisabledModuleIterator is returned from FilterDisabledModule and is used to iterate over the raw logs and unpacked data for DisabledModule events raised by the GnosisSafe contract. +type GnosisSafeDisabledModuleIterator struct { + Event *GnosisSafeDisabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeDisabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeDisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeDisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeDisabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeDisabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeDisabledModule represents a DisabledModule event raised by the GnosisSafe contract. +type GnosisSafeDisabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDisabledModule is a free log retrieval operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) FilterDisabledModule(opts *bind.FilterOpts) (*GnosisSafeDisabledModuleIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return &GnosisSafeDisabledModuleIterator{contract: _GnosisSafe.contract, event: "DisabledModule", logs: logs, sub: sub}, nil +} + +// WatchDisabledModule is a free log subscription operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) WatchDisabledModule(opts *bind.WatchOpts, sink chan<- *GnosisSafeDisabledModule) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeDisabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDisabledModule is a log parse operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) ParseDisabledModule(log types.Log) (*GnosisSafeDisabledModule, error) { + event := new(GnosisSafeDisabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeEnabledModuleIterator is returned from FilterEnabledModule and is used to iterate over the raw logs and unpacked data for EnabledModule events raised by the GnosisSafe contract. +type GnosisSafeEnabledModuleIterator struct { + Event *GnosisSafeEnabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeEnabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeEnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeEnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeEnabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeEnabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeEnabledModule represents a EnabledModule event raised by the GnosisSafe contract. +type GnosisSafeEnabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEnabledModule is a free log retrieval operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) FilterEnabledModule(opts *bind.FilterOpts) (*GnosisSafeEnabledModuleIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return &GnosisSafeEnabledModuleIterator{contract: _GnosisSafe.contract, event: "EnabledModule", logs: logs, sub: sub}, nil +} + +// WatchEnabledModule is a free log subscription operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) WatchEnabledModule(opts *bind.WatchOpts, sink chan<- *GnosisSafeEnabledModule) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeEnabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEnabledModule is a log parse operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) ParseEnabledModule(log types.Log) (*GnosisSafeEnabledModule, error) { + event := new(GnosisSafeEnabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionFailureIterator is returned from FilterExecutionFailure and is used to iterate over the raw logs and unpacked data for ExecutionFailure events raised by the GnosisSafe contract. +type GnosisSafeExecutionFailureIterator struct { + Event *GnosisSafeExecutionFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionFailure represents a ExecutionFailure event raised by the GnosisSafe contract. +type GnosisSafeExecutionFailure struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFailure is a free log retrieval operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionFailure(opts *bind.FilterOpts) (*GnosisSafeExecutionFailureIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return &GnosisSafeExecutionFailureIterator{contract: _GnosisSafe.contract, event: "ExecutionFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFailure is a free log subscription operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionFailure(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionFailure) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFailure is a log parse operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionFailure(log types.Log) (*GnosisSafeExecutionFailure, error) { + event := new(GnosisSafeExecutionFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionFromModuleFailureIterator is returned from FilterExecutionFromModuleFailure and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleFailure events raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleFailureIterator struct { + Event *GnosisSafeExecutionFromModuleFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionFromModuleFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionFromModuleFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionFromModuleFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionFromModuleFailure represents a ExecutionFromModuleFailure event raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleFailure struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleFailure is a free log retrieval operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionFromModuleFailure(opts *bind.FilterOpts, module []common.Address) (*GnosisSafeExecutionFromModuleFailureIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return &GnosisSafeExecutionFromModuleFailureIterator{contract: _GnosisSafe.contract, event: "ExecutionFromModuleFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleFailure is a free log subscription operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionFromModuleFailure(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionFromModuleFailure, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionFromModuleFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleFailure is a log parse operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionFromModuleFailure(log types.Log) (*GnosisSafeExecutionFromModuleFailure, error) { + event := new(GnosisSafeExecutionFromModuleFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionFromModuleSuccessIterator is returned from FilterExecutionFromModuleSuccess and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleSuccess events raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleSuccessIterator struct { + Event *GnosisSafeExecutionFromModuleSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionFromModuleSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionFromModuleSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionFromModuleSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionFromModuleSuccess represents a ExecutionFromModuleSuccess event raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleSuccess struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleSuccess is a free log retrieval operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionFromModuleSuccess(opts *bind.FilterOpts, module []common.Address) (*GnosisSafeExecutionFromModuleSuccessIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return &GnosisSafeExecutionFromModuleSuccessIterator{contract: _GnosisSafe.contract, event: "ExecutionFromModuleSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleSuccess is a free log subscription operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionFromModuleSuccess(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionFromModuleSuccess, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionFromModuleSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleSuccess is a log parse operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionFromModuleSuccess(log types.Log) (*GnosisSafeExecutionFromModuleSuccess, error) { + event := new(GnosisSafeExecutionFromModuleSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionSuccessIterator is returned from FilterExecutionSuccess and is used to iterate over the raw logs and unpacked data for ExecutionSuccess events raised by the GnosisSafe contract. +type GnosisSafeExecutionSuccessIterator struct { + Event *GnosisSafeExecutionSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionSuccess represents a ExecutionSuccess event raised by the GnosisSafe contract. +type GnosisSafeExecutionSuccess struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionSuccess is a free log retrieval operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionSuccess(opts *bind.FilterOpts) (*GnosisSafeExecutionSuccessIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return &GnosisSafeExecutionSuccessIterator{contract: _GnosisSafe.contract, event: "ExecutionSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionSuccess is a free log subscription operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionSuccess(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionSuccess) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionSuccess is a log parse operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionSuccess(log types.Log) (*GnosisSafeExecutionSuccess, error) { + event := new(GnosisSafeExecutionSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeRemovedOwnerIterator is returned from FilterRemovedOwner and is used to iterate over the raw logs and unpacked data for RemovedOwner events raised by the GnosisSafe contract. +type GnosisSafeRemovedOwnerIterator struct { + Event *GnosisSafeRemovedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeRemovedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeRemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeRemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeRemovedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeRemovedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeRemovedOwner represents a RemovedOwner event raised by the GnosisSafe contract. +type GnosisSafeRemovedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemovedOwner is a free log retrieval operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) FilterRemovedOwner(opts *bind.FilterOpts) (*GnosisSafeRemovedOwnerIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return &GnosisSafeRemovedOwnerIterator{contract: _GnosisSafe.contract, event: "RemovedOwner", logs: logs, sub: sub}, nil +} + +// WatchRemovedOwner is a free log subscription operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) WatchRemovedOwner(opts *bind.WatchOpts, sink chan<- *GnosisSafeRemovedOwner) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeRemovedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRemovedOwner is a log parse operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) ParseRemovedOwner(log types.Log) (*GnosisSafeRemovedOwner, error) { + event := new(GnosisSafeRemovedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeSignMsgIterator is returned from FilterSignMsg and is used to iterate over the raw logs and unpacked data for SignMsg events raised by the GnosisSafe contract. +type GnosisSafeSignMsgIterator struct { + Event *GnosisSafeSignMsg // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeSignMsgIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeSignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeSignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeSignMsgIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeSignMsgIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeSignMsg represents a SignMsg event raised by the GnosisSafe contract. +type GnosisSafeSignMsg struct { + MsgHash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignMsg is a free log retrieval operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_GnosisSafe *GnosisSafeFilterer) FilterSignMsg(opts *bind.FilterOpts, msgHash [][32]byte) (*GnosisSafeSignMsgIterator, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return &GnosisSafeSignMsgIterator{contract: _GnosisSafe.contract, event: "SignMsg", logs: logs, sub: sub}, nil +} + +// WatchSignMsg is a free log subscription operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_GnosisSafe *GnosisSafeFilterer) WatchSignMsg(opts *bind.WatchOpts, sink chan<- *GnosisSafeSignMsg, msgHash [][32]byte) (event.Subscription, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeSignMsg) + if err := _GnosisSafe.contract.UnpackLog(event, "SignMsg", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSignMsg is a log parse operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_GnosisSafe *GnosisSafeFilterer) ParseSignMsg(log types.Log) (*GnosisSafeSignMsg, error) { + event := new(GnosisSafeSignMsg) + if err := _GnosisSafe.contract.UnpackLog(event, "SignMsg", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateGnosisSafeDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployGnosisSafe( + transactionOpts, + client, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + return cmd +} + +func CreateApprovedHashesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var arg0 common.Address + var arg0Raw string + var arg1 [32]byte + var arg1Raw string + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "approved-hashes", + Short: "Call the ApprovedHashes view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if arg0Raw == "" { + return fmt.Errorf("--arg-0 argument not specified") + } else if !common.IsHexAddress(arg0Raw) { + return fmt.Errorf("--arg-0 argument is not a valid Ethereum address") + } + arg0 = common.HexToAddress(arg0Raw) + + var arg1Intermediate []byte + + var arg1IntermediateHexDecodeErr error + arg1Intermediate, arg1IntermediateHexDecodeErr = hex.DecodeString(arg1Raw) + if arg1IntermediateHexDecodeErr != nil { + return arg1IntermediateHexDecodeErr + } + + copy(arg1[:], arg1Intermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.ApprovedHashes( + arg0, + arg1, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&arg0Raw, "arg-0", "", "arg-0 argument (common.Address)") + cmd.Flags().StringVar(&arg1Raw, "arg-1", "", "arg-1 argument ([32]byte)") + + return cmd +} +func CreateDomainSeparatorCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "domain-separator", + Short: "Call the DomainSeparator view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.DomainSeparator() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateEncodeTransactionDataCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + var safeTxGas *big.Int + var safeTxGasRaw string + var baseGas *big.Int + var baseGasRaw string + var gasPrice0 *big.Int + var gasPrice0Raw string + var gasToken common.Address + var gasTokenRaw string + var refundReceiver common.Address + var refundReceiverRaw string + var _nonce0 *big.Int + var _nonce0Raw string + + var capture0 []byte + + cmd := &cobra.Command{ + Use: "encode-transaction-data", + Short: "Call the EncodeTransactionData view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if safeTxGasRaw == "" { + return fmt.Errorf("--safe-tx-gas argument not specified") + } + safeTxGas = new(big.Int) + safeTxGas.SetString(safeTxGasRaw, 0) + + if baseGasRaw == "" { + return fmt.Errorf("--base-gas argument not specified") + } + baseGas = new(big.Int) + baseGas.SetString(baseGasRaw, 0) + + if gasPrice0Raw == "" { + return fmt.Errorf("--gas-price-0 argument not specified") + } + gasPrice0 = new(big.Int) + gasPrice0.SetString(gasPrice0Raw, 0) + + if gasTokenRaw == "" { + return fmt.Errorf("--gas-token argument not specified") + } else if !common.IsHexAddress(gasTokenRaw) { + return fmt.Errorf("--gas-token argument is not a valid Ethereum address") + } + gasToken = common.HexToAddress(gasTokenRaw) + + if refundReceiverRaw == "" { + return fmt.Errorf("--refund-receiver argument not specified") + } else if !common.IsHexAddress(refundReceiverRaw) { + return fmt.Errorf("--refund-receiver argument is not a valid Ethereum address") + } + refundReceiver = common.HexToAddress(refundReceiverRaw) + + if _nonce0Raw == "" { + return fmt.Errorf("---nonce-0 argument not specified") + } + _nonce0 = new(big.Int) + _nonce0.SetString(_nonce0Raw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.EncodeTransactionData( + to0, + value0, + data, + operation, + safeTxGas, + baseGas, + gasPrice0, + gasToken, + refundReceiver, + _nonce0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + cmd.Flags().StringVar(&safeTxGasRaw, "safe-tx-gas", "", "safe-tx-gas argument") + cmd.Flags().StringVar(&baseGasRaw, "base-gas", "", "base-gas argument") + cmd.Flags().StringVar(&gasPrice0Raw, "gas-price-0", "", "gas-price-0 argument") + cmd.Flags().StringVar(&gasTokenRaw, "gas-token", "", "gas-token argument (common.Address)") + cmd.Flags().StringVar(&refundReceiverRaw, "refund-receiver", "", "refund-receiver argument (common.Address)") + cmd.Flags().StringVar(&_nonce0Raw, "-nonce-0", "", "-nonce-0 argument") + + return cmd +} +func CreateGetMessageHashCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var message []byte + var messageRaw string + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "get-message-hash", + Short: "Call the GetMessageHash view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var messageIntermediate []byte + + var messageIntermediateHexDecodeErr error + messageIntermediate, messageIntermediateHexDecodeErr = hex.DecodeString(messageRaw) + if messageIntermediateHexDecodeErr != nil { + return messageIntermediateHexDecodeErr + } + + copy(message[:], messageIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetMessageHash( + message, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&messageRaw, "message", "", "message argument ([]byte)") + + return cmd +} +func CreateGetModulesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 []common.Address + + cmd := &cobra.Command{ + Use: "get-modules", + Short: "Call the GetModules view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetModules() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateGetModulesPaginatedCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var start common.Address + var startRaw string + var pageSize *big.Int + var pageSizeRaw string + + var capture0 struct { + Array []common.Address + Next common.Address + } + + cmd := &cobra.Command{ + Use: "get-modules-paginated", + Short: "Call the GetModulesPaginated view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if startRaw == "" { + return fmt.Errorf("--start argument not specified") + } else if !common.IsHexAddress(startRaw) { + return fmt.Errorf("--start argument is not a valid Ethereum address") + } + start = common.HexToAddress(startRaw) + + if pageSizeRaw == "" { + return fmt.Errorf("--page-size argument not specified") + } + pageSize = new(big.Int) + pageSize.SetString(pageSizeRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetModulesPaginated( + start, + pageSize, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&startRaw, "start", "", "start argument (common.Address)") + cmd.Flags().StringVar(&pageSizeRaw, "page-size", "", "page-size argument") + + return cmd +} +func CreateGetOwnersCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 []common.Address + + cmd := &cobra.Command{ + Use: "get-owners", + Short: "Call the GetOwners view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetOwners() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateGetThresholdCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "get-threshold", + Short: "Call the GetThreshold view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetThreshold() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateGetTransactionHashCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + var safeTxGas *big.Int + var safeTxGasRaw string + var baseGas *big.Int + var baseGasRaw string + var gasPrice0 *big.Int + var gasPrice0Raw string + var gasToken common.Address + var gasTokenRaw string + var refundReceiver common.Address + var refundReceiverRaw string + var _nonce0 *big.Int + var _nonce0Raw string + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "get-transaction-hash", + Short: "Call the GetTransactionHash view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if safeTxGasRaw == "" { + return fmt.Errorf("--safe-tx-gas argument not specified") + } + safeTxGas = new(big.Int) + safeTxGas.SetString(safeTxGasRaw, 0) + + if baseGasRaw == "" { + return fmt.Errorf("--base-gas argument not specified") + } + baseGas = new(big.Int) + baseGas.SetString(baseGasRaw, 0) + + if gasPrice0Raw == "" { + return fmt.Errorf("--gas-price-0 argument not specified") + } + gasPrice0 = new(big.Int) + gasPrice0.SetString(gasPrice0Raw, 0) + + if gasTokenRaw == "" { + return fmt.Errorf("--gas-token argument not specified") + } else if !common.IsHexAddress(gasTokenRaw) { + return fmt.Errorf("--gas-token argument is not a valid Ethereum address") + } + gasToken = common.HexToAddress(gasTokenRaw) + + if refundReceiverRaw == "" { + return fmt.Errorf("--refund-receiver argument not specified") + } else if !common.IsHexAddress(refundReceiverRaw) { + return fmt.Errorf("--refund-receiver argument is not a valid Ethereum address") + } + refundReceiver = common.HexToAddress(refundReceiverRaw) + + if _nonce0Raw == "" { + return fmt.Errorf("---nonce-0 argument not specified") + } + _nonce0 = new(big.Int) + _nonce0.SetString(_nonce0Raw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetTransactionHash( + to0, + value0, + data, + operation, + safeTxGas, + baseGas, + gasPrice0, + gasToken, + refundReceiver, + _nonce0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + cmd.Flags().StringVar(&safeTxGasRaw, "safe-tx-gas", "", "safe-tx-gas argument") + cmd.Flags().StringVar(&baseGasRaw, "base-gas", "", "base-gas argument") + cmd.Flags().StringVar(&gasPrice0Raw, "gas-price-0", "", "gas-price-0 argument") + cmd.Flags().StringVar(&gasTokenRaw, "gas-token", "", "gas-token argument (common.Address)") + cmd.Flags().StringVar(&refundReceiverRaw, "refund-receiver", "", "refund-receiver argument (common.Address)") + cmd.Flags().StringVar(&_nonce0Raw, "-nonce-0", "", "-nonce-0 argument") + + return cmd +} +func CreateIsModuleEnabledCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var module common.Address + var moduleRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "is-module-enabled", + Short: "Call the IsModuleEnabled view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if moduleRaw == "" { + return fmt.Errorf("--module argument not specified") + } else if !common.IsHexAddress(moduleRaw) { + return fmt.Errorf("--module argument is not a valid Ethereum address") + } + module = common.HexToAddress(moduleRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.IsModuleEnabled( + module, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&moduleRaw, "module", "", "module argument (common.Address)") + + return cmd +} +func CreateIsOwnerCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var owner common.Address + var ownerRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "is-owner", + Short: "Call the IsOwner view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.IsOwner( + owner, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument (common.Address)") + + return cmd +} +func CreateNameCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 string + + cmd := &cobra.Command{ + Use: "name", + Short: "Call the NAME view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.NAME() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateNonceCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "nonce", + Short: "Call the Nonce view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.Nonce() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateSignedMessagesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var arg0 [32]byte + var arg0Raw string + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "signed-messages", + Short: "Call the SignedMessages view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var arg0Intermediate []byte + + var arg0IntermediateHexDecodeErr error + arg0Intermediate, arg0IntermediateHexDecodeErr = hex.DecodeString(arg0Raw) + if arg0IntermediateHexDecodeErr != nil { + return arg0IntermediateHexDecodeErr + } + + copy(arg0[:], arg0Intermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.SignedMessages( + arg0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&arg0Raw, "arg-0", "", "arg-0 argument ([32]byte)") + + return cmd +} +func CreateVersionCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 string + + cmd := &cobra.Command{ + Use: "version", + Short: "Call the VERSION view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.VERSION() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} + +func CreateAddOwnerWithThresholdCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var owner common.Address + var ownerRaw string + var threshold *big.Int + var thresholdRaw string + + cmd := &cobra.Command{ + Use: "add-owner-with-threshold", + Short: "Execute the AddOwnerWithThreshold method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.AddOwnerWithThreshold( + owner, + threshold, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument (common.Address)") + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + + return cmd +} +func CreateApproveHashCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var hashToApprove [32]byte + var hashToApproveRaw string + + cmd := &cobra.Command{ + Use: "approve-hash", + Short: "Execute the ApproveHash method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hashToApproveIntermediate []byte + + var hashToApproveIntermediateHexDecodeErr error + hashToApproveIntermediate, hashToApproveIntermediateHexDecodeErr = hex.DecodeString(hashToApproveRaw) + if hashToApproveIntermediateHexDecodeErr != nil { + return hashToApproveIntermediateHexDecodeErr + } + + copy(hashToApprove[:], hashToApproveIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ApproveHash( + hashToApprove, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&hashToApproveRaw, "hash-to-approve", "", "hash-to-approve argument ([32]byte)") + + return cmd +} +func CreateChangeMasterCopyCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var masterCopy common.Address + var masterCopyRaw string + + cmd := &cobra.Command{ + Use: "change-master-copy", + Short: "Execute the ChangeMasterCopy method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if masterCopyRaw == "" { + return fmt.Errorf("--master-copy argument not specified") + } else if !common.IsHexAddress(masterCopyRaw) { + return fmt.Errorf("--master-copy argument is not a valid Ethereum address") + } + masterCopy = common.HexToAddress(masterCopyRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ChangeMasterCopy( + masterCopy, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&masterCopyRaw, "master-copy", "", "master-copy argument (common.Address)") + + return cmd +} +func CreateChangeThresholdCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var threshold *big.Int + var thresholdRaw string + + cmd := &cobra.Command{ + Use: "change-threshold", + Short: "Execute the ChangeThreshold method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ChangeThreshold( + threshold, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + + return cmd +} +func CreateDisableModuleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var prevModule common.Address + var prevModuleRaw string + var module common.Address + var moduleRaw string + + cmd := &cobra.Command{ + Use: "disable-module", + Short: "Execute the DisableModule method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if prevModuleRaw == "" { + return fmt.Errorf("--prev-module argument not specified") + } else if !common.IsHexAddress(prevModuleRaw) { + return fmt.Errorf("--prev-module argument is not a valid Ethereum address") + } + prevModule = common.HexToAddress(prevModuleRaw) + + if moduleRaw == "" { + return fmt.Errorf("--module argument not specified") + } else if !common.IsHexAddress(moduleRaw) { + return fmt.Errorf("--module argument is not a valid Ethereum address") + } + module = common.HexToAddress(moduleRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.DisableModule( + prevModule, + module, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&prevModuleRaw, "prev-module", "", "prev-module argument (common.Address)") + cmd.Flags().StringVar(&moduleRaw, "module", "", "module argument (common.Address)") + + return cmd +} +func CreateEnableModuleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var module common.Address + var moduleRaw string + + cmd := &cobra.Command{ + Use: "enable-module", + Short: "Execute the EnableModule method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if moduleRaw == "" { + return fmt.Errorf("--module argument not specified") + } else if !common.IsHexAddress(moduleRaw) { + return fmt.Errorf("--module argument is not a valid Ethereum address") + } + module = common.HexToAddress(moduleRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.EnableModule( + module, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&moduleRaw, "module", "", "module argument (common.Address)") + + return cmd +} +func CreateExecTransactionCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + var safeTxGas *big.Int + var safeTxGasRaw string + var baseGas *big.Int + var baseGasRaw string + var gasPrice0 *big.Int + var gasPrice0Raw string + var gasToken common.Address + var gasTokenRaw string + var refundReceiver common.Address + var refundReceiverRaw string + var signatures []byte + var signaturesRaw string + + cmd := &cobra.Command{ + Use: "exec-transaction", + Short: "Execute the ExecTransaction method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if safeTxGasRaw == "" { + return fmt.Errorf("--safe-tx-gas argument not specified") + } + safeTxGas = new(big.Int) + safeTxGas.SetString(safeTxGasRaw, 0) + + if baseGasRaw == "" { + return fmt.Errorf("--base-gas argument not specified") + } + baseGas = new(big.Int) + baseGas.SetString(baseGasRaw, 0) + + if gasPrice0Raw == "" { + return fmt.Errorf("--gas-price-0 argument not specified") + } + gasPrice0 = new(big.Int) + gasPrice0.SetString(gasPrice0Raw, 0) + + if gasTokenRaw == "" { + return fmt.Errorf("--gas-token argument not specified") + } else if !common.IsHexAddress(gasTokenRaw) { + return fmt.Errorf("--gas-token argument is not a valid Ethereum address") + } + gasToken = common.HexToAddress(gasTokenRaw) + + if refundReceiverRaw == "" { + return fmt.Errorf("--refund-receiver argument not specified") + } else if !common.IsHexAddress(refundReceiverRaw) { + return fmt.Errorf("--refund-receiver argument is not a valid Ethereum address") + } + refundReceiver = common.HexToAddress(refundReceiverRaw) + + var signaturesIntermediate []byte + + var signaturesIntermediateHexDecodeErr error + signaturesIntermediate, signaturesIntermediateHexDecodeErr = hex.DecodeString(signaturesRaw) + if signaturesIntermediateHexDecodeErr != nil { + return signaturesIntermediateHexDecodeErr + } + + copy(signatures[:], signaturesIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ExecTransaction( + to0, + value0, + data, + operation, + safeTxGas, + baseGas, + gasPrice0, + gasToken, + refundReceiver, + signatures, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + cmd.Flags().StringVar(&safeTxGasRaw, "safe-tx-gas", "", "safe-tx-gas argument") + cmd.Flags().StringVar(&baseGasRaw, "base-gas", "", "base-gas argument") + cmd.Flags().StringVar(&gasPrice0Raw, "gas-price-0", "", "gas-price-0 argument") + cmd.Flags().StringVar(&gasTokenRaw, "gas-token", "", "gas-token argument (common.Address)") + cmd.Flags().StringVar(&refundReceiverRaw, "refund-receiver", "", "refund-receiver argument (common.Address)") + cmd.Flags().StringVar(&signaturesRaw, "signatures", "", "signatures argument ([]byte)") + + return cmd +} +func CreateExecTransactionFromModuleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + cmd := &cobra.Command{ + Use: "exec-transaction-from-module", + Short: "Execute the ExecTransactionFromModule method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ExecTransactionFromModule( + to0, + value0, + data, + operation, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + + return cmd +} +func CreateExecTransactionFromModuleReturnDataCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + cmd := &cobra.Command{ + Use: "exec-transaction-from-module-return-data", + Short: "Execute the ExecTransactionFromModuleReturnData method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ExecTransactionFromModuleReturnData( + to0, + value0, + data, + operation, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + + return cmd +} +func CreateFallbackCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var calldata []byte + var calldataRaw string + + cmd := &cobra.Command{ + Use: "fallback", + Short: "Execute the Fallback method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var calldataIntermediate []byte + + var calldataIntermediateHexDecodeErr error + calldataIntermediate, calldataIntermediateHexDecodeErr = hex.DecodeString(calldataRaw) + if calldataIntermediateHexDecodeErr != nil { + return calldataIntermediateHexDecodeErr + } + + copy(calldata[:], calldataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Fallback( + calldata, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&calldataRaw, "calldata", "", "calldata argument ([]byte)") + + return cmd +} +func CreateIsValidSignatureCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var data []byte + var dataRaw string + var signature []byte + var signatureRaw string + + cmd := &cobra.Command{ + Use: "is-valid-signature", + Short: "Execute the IsValidSignature method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + var signatureIntermediate []byte + + var signatureIntermediateHexDecodeErr error + signatureIntermediate, signatureIntermediateHexDecodeErr = hex.DecodeString(signatureRaw) + if signatureIntermediateHexDecodeErr != nil { + return signatureIntermediateHexDecodeErr + } + + copy(signature[:], signatureIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.IsValidSignature( + data, + signature, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().StringVar(&signatureRaw, "signature", "", "signature argument ([]byte)") + + return cmd +} +func CreateRemoveOwnerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var prevOwner common.Address + var prevOwnerRaw string + var owner common.Address + var ownerRaw string + var threshold *big.Int + var thresholdRaw string + + cmd := &cobra.Command{ + Use: "remove-owner", + Short: "Execute the RemoveOwner method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if prevOwnerRaw == "" { + return fmt.Errorf("--prev-owner argument not specified") + } else if !common.IsHexAddress(prevOwnerRaw) { + return fmt.Errorf("--prev-owner argument is not a valid Ethereum address") + } + prevOwner = common.HexToAddress(prevOwnerRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.RemoveOwner( + prevOwner, + owner, + threshold, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&prevOwnerRaw, "prev-owner", "", "prev-owner argument (common.Address)") + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument (common.Address)") + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + + return cmd +} +func CreateRequiredTxGasCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + cmd := &cobra.Command{ + Use: "required-tx-gas", + Short: "Execute the RequiredTxGas method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.RequiredTxGas( + to0, + value0, + data, + operation, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + + return cmd +} +func CreateSetFallbackHandlerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var handler common.Address + var handlerRaw string + + cmd := &cobra.Command{ + Use: "set-fallback-handler", + Short: "Execute the SetFallbackHandler method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if handlerRaw == "" { + return fmt.Errorf("--handler argument not specified") + } else if !common.IsHexAddress(handlerRaw) { + return fmt.Errorf("--handler argument is not a valid Ethereum address") + } + handler = common.HexToAddress(handlerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SetFallbackHandler( + handler, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&handlerRaw, "handler", "", "handler argument (common.Address)") + + return cmd +} +func CreateSetupCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var owners []common.Address + var ownersRaw string + var threshold *big.Int + var thresholdRaw string + var to0 common.Address + var to0Raw string + var data []byte + var dataRaw string + var fallbackHandler common.Address + var fallbackHandlerRaw string + var paymentToken common.Address + var paymentTokenRaw string + var payment *big.Int + var paymentRaw string + var paymentReceiver common.Address + var paymentReceiverRaw string + + cmd := &cobra.Command{ + Use: "setup", + Short: "Execute the Setup method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownersRaw == "" { + return fmt.Errorf("--owners argument not specified") + } else if strings.HasPrefix(ownersRaw, "@") { + filename := strings.TrimPrefix(ownersRaw, "@") + contents, readErr := os.ReadFile(filename) + if readErr != nil { + return readErr + } + unmarshalErr := json.Unmarshal(contents, &owners) + if unmarshalErr != nil { + return unmarshalErr + } + } else { + unmarshalErr := json.Unmarshal([]byte(ownersRaw), &owners) + if unmarshalErr != nil { + return unmarshalErr + } + } + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if fallbackHandlerRaw == "" { + return fmt.Errorf("--fallback-handler argument not specified") + } else if !common.IsHexAddress(fallbackHandlerRaw) { + return fmt.Errorf("--fallback-handler argument is not a valid Ethereum address") + } + fallbackHandler = common.HexToAddress(fallbackHandlerRaw) + + if paymentTokenRaw == "" { + return fmt.Errorf("--payment-token argument not specified") + } else if !common.IsHexAddress(paymentTokenRaw) { + return fmt.Errorf("--payment-token argument is not a valid Ethereum address") + } + paymentToken = common.HexToAddress(paymentTokenRaw) + + if paymentRaw == "" { + return fmt.Errorf("--payment argument not specified") + } + payment = new(big.Int) + payment.SetString(paymentRaw, 0) + + if paymentReceiverRaw == "" { + return fmt.Errorf("--payment-receiver argument not specified") + } else if !common.IsHexAddress(paymentReceiverRaw) { + return fmt.Errorf("--payment-receiver argument is not a valid Ethereum address") + } + paymentReceiver = common.HexToAddress(paymentReceiverRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Setup( + owners, + threshold, + to0, + data, + fallbackHandler, + paymentToken, + payment, + paymentReceiver, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&ownersRaw, "owners", "", "owners argument ([]common.Address)") + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().StringVar(&fallbackHandlerRaw, "fallback-handler", "", "fallback-handler argument (common.Address)") + cmd.Flags().StringVar(&paymentTokenRaw, "payment-token", "", "payment-token argument (common.Address)") + cmd.Flags().StringVar(&paymentRaw, "payment", "", "payment argument") + cmd.Flags().StringVar(&paymentReceiverRaw, "payment-receiver", "", "payment-receiver argument (common.Address)") + + return cmd +} +func CreateSignMessageCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var data []byte + var dataRaw string + + cmd := &cobra.Command{ + Use: "sign-message", + Short: "Execute the SignMessage method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SignMessage( + data, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + + return cmd +} +func CreateSwapOwnerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var prevOwner common.Address + var prevOwnerRaw string + var oldOwner common.Address + var oldOwnerRaw string + var newOwner common.Address + var newOwnerRaw string + + cmd := &cobra.Command{ + Use: "swap-owner", + Short: "Execute the SwapOwner method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if prevOwnerRaw == "" { + return fmt.Errorf("--prev-owner argument not specified") + } else if !common.IsHexAddress(prevOwnerRaw) { + return fmt.Errorf("--prev-owner argument is not a valid Ethereum address") + } + prevOwner = common.HexToAddress(prevOwnerRaw) + + if oldOwnerRaw == "" { + return fmt.Errorf("--old-owner argument not specified") + } else if !common.IsHexAddress(oldOwnerRaw) { + return fmt.Errorf("--old-owner argument is not a valid Ethereum address") + } + oldOwner = common.HexToAddress(oldOwnerRaw) + + if newOwnerRaw == "" { + return fmt.Errorf("--new-owner argument not specified") + } else if !common.IsHexAddress(newOwnerRaw) { + return fmt.Errorf("--new-owner argument is not a valid Ethereum address") + } + newOwner = common.HexToAddress(newOwnerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SwapOwner( + prevOwner, + oldOwner, + newOwner, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&prevOwnerRaw, "prev-owner", "", "prev-owner argument (common.Address)") + cmd.Flags().StringVar(&oldOwnerRaw, "old-owner", "", "old-owner argument (common.Address)") + cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the GNOSIS_SAFE_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the GNOSIS_SAFE_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("GNOSIS_SAFE_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateGnosisSafeCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "gnosis-safe", + Short: "Interact with the GnosisSafe contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployGnosisSafe := CreateGnosisSafeDeploymentCommand() + cmdDeployGnosisSafe.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployGnosisSafe) + + cmdViewApprovedHashes := CreateApprovedHashesCommand() + cmdViewApprovedHashes.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewApprovedHashes) + cmdViewDomainSeparator := CreateDomainSeparatorCommand() + cmdViewDomainSeparator.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewDomainSeparator) + cmdViewEncodeTransactionData := CreateEncodeTransactionDataCommand() + cmdViewEncodeTransactionData.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewEncodeTransactionData) + cmdViewGetMessageHash := CreateGetMessageHashCommand() + cmdViewGetMessageHash.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetMessageHash) + cmdViewGetModules := CreateGetModulesCommand() + cmdViewGetModules.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetModules) + cmdViewGetModulesPaginated := CreateGetModulesPaginatedCommand() + cmdViewGetModulesPaginated.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetModulesPaginated) + cmdViewGetOwners := CreateGetOwnersCommand() + cmdViewGetOwners.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetOwners) + cmdViewGetThreshold := CreateGetThresholdCommand() + cmdViewGetThreshold.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetThreshold) + cmdViewGetTransactionHash := CreateGetTransactionHashCommand() + cmdViewGetTransactionHash.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetTransactionHash) + cmdViewIsModuleEnabled := CreateIsModuleEnabledCommand() + cmdViewIsModuleEnabled.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewIsModuleEnabled) + cmdViewIsOwner := CreateIsOwnerCommand() + cmdViewIsOwner.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewIsOwner) + cmdViewNAME := CreateNameCommand() + cmdViewNAME.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewNAME) + cmdViewNonce := CreateNonceCommand() + cmdViewNonce.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewNonce) + cmdViewSignedMessages := CreateSignedMessagesCommand() + cmdViewSignedMessages.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewSignedMessages) + cmdViewVERSION := CreateVersionCommand() + cmdViewVERSION.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewVERSION) + + cmdTransactAddOwnerWithThreshold := CreateAddOwnerWithThresholdCommand() + cmdTransactAddOwnerWithThreshold.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactAddOwnerWithThreshold) + cmdTransactApproveHash := CreateApproveHashCommand() + cmdTransactApproveHash.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactApproveHash) + cmdTransactChangeMasterCopy := CreateChangeMasterCopyCommand() + cmdTransactChangeMasterCopy.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactChangeMasterCopy) + cmdTransactChangeThreshold := CreateChangeThresholdCommand() + cmdTransactChangeThreshold.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactChangeThreshold) + cmdTransactDisableModule := CreateDisableModuleCommand() + cmdTransactDisableModule.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactDisableModule) + cmdTransactEnableModule := CreateEnableModuleCommand() + cmdTransactEnableModule.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactEnableModule) + cmdTransactExecTransaction := CreateExecTransactionCommand() + cmdTransactExecTransaction.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactExecTransaction) + cmdTransactExecTransactionFromModule := CreateExecTransactionFromModuleCommand() + cmdTransactExecTransactionFromModule.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactExecTransactionFromModule) + cmdTransactExecTransactionFromModuleReturnData := CreateExecTransactionFromModuleReturnDataCommand() + cmdTransactExecTransactionFromModuleReturnData.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactExecTransactionFromModuleReturnData) + cmdTransactFallback := CreateFallbackCommand() + cmdTransactFallback.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactFallback) + cmdTransactIsValidSignature := CreateIsValidSignatureCommand() + cmdTransactIsValidSignature.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactIsValidSignature) + cmdTransactRemoveOwner := CreateRemoveOwnerCommand() + cmdTransactRemoveOwner.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRemoveOwner) + cmdTransactRequiredTxGas := CreateRequiredTxGasCommand() + cmdTransactRequiredTxGas.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRequiredTxGas) + cmdTransactSetFallbackHandler := CreateSetFallbackHandlerCommand() + cmdTransactSetFallbackHandler.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSetFallbackHandler) + cmdTransactSetup := CreateSetupCommand() + cmdTransactSetup.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSetup) + cmdTransactSignMessage := CreateSignMessageCommand() + cmdTransactSignMessage.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSignMessage) + cmdTransactSwapOwner := CreateSwapOwnerCommand() + cmdTransactSwapOwner.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSwapOwner) + + return cmd +} diff --git a/bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go b/bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go new file mode 100644 index 0000000..5b7c97e --- /dev/null +++ b/bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go @@ -0,0 +1,985 @@ +// This file was generated by seer: https://github.com/moonstream-to/seer. +// seer version: 0.1.20 +// seer command: seer evm generate --package ImmutableCreate2Factory --cli --struct ImmutableCreate2Factory --output bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ImmutableCreate2Factory + +import ( + "errors" + "math/big" + "strings" + + "context" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + // Reference imports to suppress errors if they are not otherwise used. + "encoding/hex" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ImmutableCreate2FactoryMetaData contains all meta data concerning the ImmutableCreate2Factory contract. +var ImmutableCreate2FactoryMetaData = &bind.MetaData{ + ABI: "[{\"constant\":true,\"inputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"name\":\"hasBeenDeployed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"safeCreate2\",\"outputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"findCreate2Address\",\"outputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initCodeHash\",\"type\":\"bytes32\"}],\"name\":\"findCreate2AddressViaHash\",\"outputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610833806100206000396000f3fe60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a7230582000b83240d6a142e399c7c44e5b6473d34001d171630229df870513bfb4740e2d64736f6c634300050a0032", +} + +// ImmutableCreate2FactoryABI is the input ABI used to generate the binding from. +// Deprecated: Use ImmutableCreate2FactoryMetaData.ABI instead. +var ImmutableCreate2FactoryABI = ImmutableCreate2FactoryMetaData.ABI + +// ImmutableCreate2FactoryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ImmutableCreate2FactoryMetaData.Bin instead. +var ImmutableCreate2FactoryBin = ImmutableCreate2FactoryMetaData.Bin + +// DeployImmutableCreate2Factory deploys a new Ethereum contract, binding an instance of ImmutableCreate2Factory to it. +func DeployImmutableCreate2Factory(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ImmutableCreate2Factory, error) { + parsed, err := ImmutableCreate2FactoryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ImmutableCreate2FactoryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ImmutableCreate2Factory{ImmutableCreate2FactoryCaller: ImmutableCreate2FactoryCaller{contract: contract}, ImmutableCreate2FactoryTransactor: ImmutableCreate2FactoryTransactor{contract: contract}, ImmutableCreate2FactoryFilterer: ImmutableCreate2FactoryFilterer{contract: contract}}, nil +} + +// ImmutableCreate2Factory is an auto generated Go binding around an Ethereum contract. +type ImmutableCreate2Factory struct { + ImmutableCreate2FactoryCaller // Read-only binding to the contract + ImmutableCreate2FactoryTransactor // Write-only binding to the contract + ImmutableCreate2FactoryFilterer // Log filterer for contract events +} + +// ImmutableCreate2FactoryCaller is an auto generated read-only Go binding around an Ethereum contract. +type ImmutableCreate2FactoryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ImmutableCreate2FactoryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ImmutableCreate2FactoryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ImmutableCreate2FactoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ImmutableCreate2FactoryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ImmutableCreate2FactorySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ImmutableCreate2FactorySession struct { + Contract *ImmutableCreate2Factory // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ImmutableCreate2FactoryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ImmutableCreate2FactoryCallerSession struct { + Contract *ImmutableCreate2FactoryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ImmutableCreate2FactoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ImmutableCreate2FactoryTransactorSession struct { + Contract *ImmutableCreate2FactoryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ImmutableCreate2FactoryRaw is an auto generated low-level Go binding around an Ethereum contract. +type ImmutableCreate2FactoryRaw struct { + Contract *ImmutableCreate2Factory // Generic contract binding to access the raw methods on +} + +// ImmutableCreate2FactoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ImmutableCreate2FactoryCallerRaw struct { + Contract *ImmutableCreate2FactoryCaller // Generic read-only contract binding to access the raw methods on +} + +// ImmutableCreate2FactoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ImmutableCreate2FactoryTransactorRaw struct { + Contract *ImmutableCreate2FactoryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewImmutableCreate2Factory creates a new instance of ImmutableCreate2Factory, bound to a specific deployed contract. +func NewImmutableCreate2Factory(address common.Address, backend bind.ContractBackend) (*ImmutableCreate2Factory, error) { + contract, err := bindImmutableCreate2Factory(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ImmutableCreate2Factory{ImmutableCreate2FactoryCaller: ImmutableCreate2FactoryCaller{contract: contract}, ImmutableCreate2FactoryTransactor: ImmutableCreate2FactoryTransactor{contract: contract}, ImmutableCreate2FactoryFilterer: ImmutableCreate2FactoryFilterer{contract: contract}}, nil +} + +// NewImmutableCreate2FactoryCaller creates a new read-only instance of ImmutableCreate2Factory, bound to a specific deployed contract. +func NewImmutableCreate2FactoryCaller(address common.Address, caller bind.ContractCaller) (*ImmutableCreate2FactoryCaller, error) { + contract, err := bindImmutableCreate2Factory(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ImmutableCreate2FactoryCaller{contract: contract}, nil +} + +// NewImmutableCreate2FactoryTransactor creates a new write-only instance of ImmutableCreate2Factory, bound to a specific deployed contract. +func NewImmutableCreate2FactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*ImmutableCreate2FactoryTransactor, error) { + contract, err := bindImmutableCreate2Factory(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ImmutableCreate2FactoryTransactor{contract: contract}, nil +} + +// NewImmutableCreate2FactoryFilterer creates a new log filterer instance of ImmutableCreate2Factory, bound to a specific deployed contract. +func NewImmutableCreate2FactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*ImmutableCreate2FactoryFilterer, error) { + contract, err := bindImmutableCreate2Factory(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ImmutableCreate2FactoryFilterer{contract: contract}, nil +} + +// bindImmutableCreate2Factory binds a generic wrapper to an already deployed contract. +func bindImmutableCreate2Factory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ImmutableCreate2FactoryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ImmutableCreate2Factory.Contract.ImmutableCreate2FactoryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ImmutableCreate2Factory.Contract.ImmutableCreate2FactoryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ImmutableCreate2Factory.Contract.ImmutableCreate2FactoryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ImmutableCreate2Factory.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ImmutableCreate2Factory.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ImmutableCreate2Factory.Contract.contract.Transact(opts, method, params...) +} + +// FindCreate2Address is a free data retrieval call binding the contract method 0x85cf97ab. +// +// Solidity: function findCreate2Address(bytes32 salt, bytes initCode) view returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCaller) FindCreate2Address(opts *bind.CallOpts, salt [32]byte, initCode []byte) (common.Address, error) { + var out []interface{} + err := _ImmutableCreate2Factory.contract.Call(opts, &out, "findCreate2Address", salt, initCode) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// FindCreate2Address is a free data retrieval call binding the contract method 0x85cf97ab. +// +// Solidity: function findCreate2Address(bytes32 salt, bytes initCode) view returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) FindCreate2Address(salt [32]byte, initCode []byte) (common.Address, error) { + return _ImmutableCreate2Factory.Contract.FindCreate2Address(&_ImmutableCreate2Factory.CallOpts, salt, initCode) +} + +// FindCreate2Address is a free data retrieval call binding the contract method 0x85cf97ab. +// +// Solidity: function findCreate2Address(bytes32 salt, bytes initCode) view returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerSession) FindCreate2Address(salt [32]byte, initCode []byte) (common.Address, error) { + return _ImmutableCreate2Factory.Contract.FindCreate2Address(&_ImmutableCreate2Factory.CallOpts, salt, initCode) +} + +// FindCreate2AddressViaHash is a free data retrieval call binding the contract method 0xa49a7c90. +// +// Solidity: function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) view returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCaller) FindCreate2AddressViaHash(opts *bind.CallOpts, salt [32]byte, initCodeHash [32]byte) (common.Address, error) { + var out []interface{} + err := _ImmutableCreate2Factory.contract.Call(opts, &out, "findCreate2AddressViaHash", salt, initCodeHash) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// FindCreate2AddressViaHash is a free data retrieval call binding the contract method 0xa49a7c90. +// +// Solidity: function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) view returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) FindCreate2AddressViaHash(salt [32]byte, initCodeHash [32]byte) (common.Address, error) { + return _ImmutableCreate2Factory.Contract.FindCreate2AddressViaHash(&_ImmutableCreate2Factory.CallOpts, salt, initCodeHash) +} + +// FindCreate2AddressViaHash is a free data retrieval call binding the contract method 0xa49a7c90. +// +// Solidity: function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) view returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerSession) FindCreate2AddressViaHash(salt [32]byte, initCodeHash [32]byte) (common.Address, error) { + return _ImmutableCreate2Factory.Contract.FindCreate2AddressViaHash(&_ImmutableCreate2Factory.CallOpts, salt, initCodeHash) +} + +// HasBeenDeployed is a free data retrieval call binding the contract method 0x08508b8f. +// +// Solidity: function hasBeenDeployed(address deploymentAddress) view returns(bool) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCaller) HasBeenDeployed(opts *bind.CallOpts, deploymentAddress common.Address) (bool, error) { + var out []interface{} + err := _ImmutableCreate2Factory.contract.Call(opts, &out, "hasBeenDeployed", deploymentAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// HasBeenDeployed is a free data retrieval call binding the contract method 0x08508b8f. +// +// Solidity: function hasBeenDeployed(address deploymentAddress) view returns(bool) +func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) HasBeenDeployed(deploymentAddress common.Address) (bool, error) { + return _ImmutableCreate2Factory.Contract.HasBeenDeployed(&_ImmutableCreate2Factory.CallOpts, deploymentAddress) +} + +// HasBeenDeployed is a free data retrieval call binding the contract method 0x08508b8f. +// +// Solidity: function hasBeenDeployed(address deploymentAddress) view returns(bool) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerSession) HasBeenDeployed(deploymentAddress common.Address) (bool, error) { + return _ImmutableCreate2Factory.Contract.HasBeenDeployed(&_ImmutableCreate2Factory.CallOpts, deploymentAddress) +} + +// SafeCreate2 is a paid mutator transaction binding the contract method 0x64e03087. +// +// Solidity: function safeCreate2(bytes32 salt, bytes initializationCode) payable returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactor) SafeCreate2(opts *bind.TransactOpts, salt [32]byte, initializationCode []byte) (*types.Transaction, error) { + return _ImmutableCreate2Factory.contract.Transact(opts, "safeCreate2", salt, initializationCode) +} + +// SafeCreate2 is a paid mutator transaction binding the contract method 0x64e03087. +// +// Solidity: function safeCreate2(bytes32 salt, bytes initializationCode) payable returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) SafeCreate2(salt [32]byte, initializationCode []byte) (*types.Transaction, error) { + return _ImmutableCreate2Factory.Contract.SafeCreate2(&_ImmutableCreate2Factory.TransactOpts, salt, initializationCode) +} + +// SafeCreate2 is a paid mutator transaction binding the contract method 0x64e03087. +// +// Solidity: function safeCreate2(bytes32 salt, bytes initializationCode) payable returns(address deploymentAddress) +func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactorSession) SafeCreate2(salt [32]byte, initializationCode []byte) (*types.Transaction, error) { + return _ImmutableCreate2Factory.Contract.SafeCreate2(&_ImmutableCreate2Factory.TransactOpts, salt, initializationCode) +} + +func CreateImmutableCreate2FactoryDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new ImmutableCreate2Factory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployImmutableCreate2Factory( + transactionOpts, + client, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + return cmd +} + +func CreateFindCreate2AddressCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var salt [32]byte + var saltRaw string + var initCode []byte + var initCodeRaw string + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "find-create-2-address", + Short: "Call the FindCreate2Address view method on a ImmutableCreate2Factory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var saltIntermediate []byte + + var saltIntermediateHexDecodeErr error + saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) + if saltIntermediateHexDecodeErr != nil { + return saltIntermediateHexDecodeErr + } + + copy(salt[:], saltIntermediate) + + var initCodeIntermediate []byte + + var initCodeIntermediateHexDecodeErr error + initCodeIntermediate, initCodeIntermediateHexDecodeErr = hex.DecodeString(initCodeRaw) + if initCodeIntermediateHexDecodeErr != nil { + return initCodeIntermediateHexDecodeErr + } + + copy(initCode[:], initCodeIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := ImmutableCreate2FactoryCallerSession{ + Contract: &contract.ImmutableCreate2FactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.FindCreate2Address( + salt, + initCode, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") + cmd.Flags().StringVar(&initCodeRaw, "init-code", "", "init-code argument ([]byte)") + + return cmd +} +func CreateFindCreate2AddressViaHashCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var salt [32]byte + var saltRaw string + var initCodeHash [32]byte + var initCodeHashRaw string + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "find-create-2-address-via-hash", + Short: "Call the FindCreate2AddressViaHash view method on a ImmutableCreate2Factory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var saltIntermediate []byte + + var saltIntermediateHexDecodeErr error + saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) + if saltIntermediateHexDecodeErr != nil { + return saltIntermediateHexDecodeErr + } + + copy(salt[:], saltIntermediate) + + var initCodeHashIntermediate []byte + + var initCodeHashIntermediateHexDecodeErr error + initCodeHashIntermediate, initCodeHashIntermediateHexDecodeErr = hex.DecodeString(initCodeHashRaw) + if initCodeHashIntermediateHexDecodeErr != nil { + return initCodeHashIntermediateHexDecodeErr + } + + copy(initCodeHash[:], initCodeHashIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := ImmutableCreate2FactoryCallerSession{ + Contract: &contract.ImmutableCreate2FactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.FindCreate2AddressViaHash( + salt, + initCodeHash, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") + cmd.Flags().StringVar(&initCodeHashRaw, "init-code-hash", "", "init-code-hash argument ([32]byte)") + + return cmd +} +func CreateHasBeenDeployedCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var deploymentAddress common.Address + var deploymentAddressRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "has-been-deployed", + Short: "Call the HasBeenDeployed view method on a ImmutableCreate2Factory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if deploymentAddressRaw == "" { + return fmt.Errorf("--deployment-address argument not specified") + } else if !common.IsHexAddress(deploymentAddressRaw) { + return fmt.Errorf("--deployment-address argument is not a valid Ethereum address") + } + deploymentAddress = common.HexToAddress(deploymentAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := ImmutableCreate2FactoryCallerSession{ + Contract: &contract.ImmutableCreate2FactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.HasBeenDeployed( + deploymentAddress, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&deploymentAddressRaw, "deployment-address", "", "deployment-address argument (common.Address)") + + return cmd +} + +func CreateSafeCreate2Command() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var salt [32]byte + var saltRaw string + var initializationCode []byte + var initializationCodeRaw string + + cmd := &cobra.Command{ + Use: "safe-create-2", + Short: "Execute the SafeCreate2 method on a ImmutableCreate2Factory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var saltIntermediate []byte + + var saltIntermediateHexDecodeErr error + saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) + if saltIntermediateHexDecodeErr != nil { + return saltIntermediateHexDecodeErr + } + + copy(salt[:], saltIntermediate) + + var initializationCodeIntermediate []byte + + var initializationCodeIntermediateHexDecodeErr error + initializationCodeIntermediate, initializationCodeIntermediateHexDecodeErr = hex.DecodeString(initializationCodeRaw) + if initializationCodeIntermediateHexDecodeErr != nil { + return initializationCodeIntermediateHexDecodeErr + } + + copy(initializationCode[:], initializationCodeIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := ImmutableCreate2FactoryTransactorSession{ + Contract: &contract.ImmutableCreate2FactoryTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SafeCreate2( + salt, + initializationCode, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") + cmd.Flags().StringVar(&initializationCodeRaw, "initialization-code", "", "initialization-code argument ([]byte)") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the IMMUTABLE_CREATE_2_FACTORY_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the IMMUTABLE_CREATE_2_FACTORY_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("IMMUTABLE_CREATE_2_FACTORY_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateImmutableCreate2FactoryCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "immutable-create-2-factory", + Short: "Interact with the ImmutableCreate2Factory contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployImmutableCreate2Factory := CreateImmutableCreate2FactoryDeploymentCommand() + cmdDeployImmutableCreate2Factory.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployImmutableCreate2Factory) + + cmdViewFindCreate2Address := CreateFindCreate2AddressCommand() + cmdViewFindCreate2Address.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewFindCreate2Address) + cmdViewFindCreate2AddressViaHash := CreateFindCreate2AddressViaHashCommand() + cmdViewFindCreate2AddressViaHash.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewFindCreate2AddressViaHash) + cmdViewHasBeenDeployed := CreateHasBeenDeployedCommand() + cmdViewHasBeenDeployed.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewHasBeenDeployed) + + cmdTransactSafeCreate2 := CreateSafeCreate2Command() + cmdTransactSafeCreate2.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSafeCreate2) + + return cmd +} diff --git a/evm/generators.go b/evm/generators.go index c33c983..acf1ad8 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -905,10 +905,11 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, if formattingErr != nil { return code, formattingErr } + code = string(generatedCode) } - - return code, nil + codeImportsFixed := strings.ReplaceAll(code, "github.com/quan8/go-ethereum", "github.com/ethereum/go-ethereum") + return codeImportsFixed, nil } // This template is used to generate the skeleton of the CLI, along with all utility methods that can be @@ -1066,6 +1067,239 @@ func Create{{.StructName}}Command() *cobra.Command { return cmd } + +// OperationType represents the type of operation for a Safe transaction +type OperationType uint8 + +const ( + Call OperationType = 0 + DelegateCall OperationType = 1 +) + +// String returns the string representation of the OperationType +func (o OperationType) String() string { + switch o { + case Call: + return "Call" + case DelegateCall: + return "DelegateCall" + default: + return "Unknown" + } +} + +// SafeTransactionData represents the data for a Safe transaction +type SafeTransactionData struct { + To string ` + "`" + `json:"to"` + "`" + ` + Value string ` + "`" + `json:"value"` + "`" + ` + Data string ` + "`" + `json:"data"` + "`" + ` + Operation OperationType ` + "`" + `json:"operation"` + "`" + ` + SafeTxGas uint64 ` + "`" + `json:"safeTxGas"` + "`" + ` + BaseGas uint64 ` + "`" + `json:"baseGas"` + "`" + ` + GasPrice string ` + "`" + `json:"gasPrice"` + "`" + ` + GasToken string ` + "`" + `json:"gasToken"` + "`" + ` + RefundReceiver string ` + "`" + `json:"refundReceiver"` + "`" + ` + Nonce uint64 ` + "`" + `json:"nonce"` + "`" + ` + SafeTxHash string ` + "`" + `json:"safeTxHash"` + "`" + ` + Sender string ` + "`" + `json:"sender"` + "`" + ` + Signature string ` + "`" + `json:"signature"` + "`" + ` + Origin string ` + "`" + `json:"origin"` + "`" + ` +} + +const ( + NativeTokenAddress = "0x0000000000000000000000000000000000000000" +) + + +func DeployWithSafe(rpcURL string, keyfile string, password string, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte) error { + // Generate salt + salt, err := GenerateProperSalt(safeAddress) + if err != nil { + return fmt.Errorf("failed to generate salt: %v", err) + } + + abi, err := ImmutableCreate2Factory.ImmutableCreate2FactoryMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + safeCreate2TxData, err := abi.Pack("safeCreate2", salt, deployBytecode) + if err != nil { + return fmt.Errorf("failed to pack safeCreate2 transaction: %v", err) + } + + return CreateSafeProposal(rpcURL, keyfile, password, safeAddress, factoryAddress, safeCreate2TxData, value, txServiceBaseUrl) +} + +func GenerateProperSalt(from common.Address) ([32]byte, error) { + var salt [32]byte + + // Copy the 'from' address to the first 20 bytes of the salt + copy(salt[:20], from[:]) + + // Generate random bytes for the remaining 12 bytes + _, err := rand.Read(salt[20:]) + if err != nil { + return [32]byte{}, fmt.Errorf("failed to generate random bytes: %w", err) + } + + return salt, nil +} + +func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string) error { + key, err := KeyFromFile(keyfile, password) + if err != nil { + return fmt.Errorf("failed to load key from file: %v", err) + } + + client, err := ethclient.Dial(rpcURL) + if err != nil { + return fmt.Errorf("failed to connect to the Ethereum client: %v", err) + } + + chainID, err := client.ChainID(context.Background()) + if err != nil { + return fmt.Errorf("failed to get chain ID: %v", err) + } + + // Create a new instance of the GnosisSafe contract + safeInstance, err := GnosisSafe.NewGnosisSafe(safeAddress, client) + if err != nil { + return fmt.Errorf("failed to create GnosisSafe instance: %v", err) + } + + // Fetch the current nonce from the Safe contract + nonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + + safeTransactionData := SafeTransactionData{ + To: to.Hex(), + Value: value.String(), + Data: common.Bytes2Hex(data), + Operation: Call, + SafeTxGas: 0, + BaseGas: 0, + GasPrice: "0", + GasToken: NativeTokenAddress, + RefundReceiver: NativeTokenAddress, + Nonce: nonce.Uint64(), + } + + // Calculate SafeTxHash + safeTxHash, err := CalculateSafeTxHash(safeAddress, safeTransactionData, chainID) + if err != nil { + return fmt.Errorf("failed to calculate SafeTxHash: %v", err) + } + + // Sign the SafeTxHash + signature, err := crypto.Sign(safeTxHash.Bytes(), key.PrivateKey) + if err != nil { + return fmt.Errorf("failed to sign SafeTxHash: %v", err) + } + + // Adjust V value for Ethereum's replay protection + signature[64] += 27 + + // Convert signature to hex + senderSignature := "0x" + common.Bytes2Hex(signature) + + // Prepare the request body + requestBody := map[string]interface{}{ + "to": safeTransactionData.To, + "value": safeTransactionData.Value, + "data": "0x" + safeTransactionData.Data, + "operation": int(safeTransactionData.Operation), + "safeTxGas": fmt.Sprintf("%d", safeTransactionData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", safeTransactionData.BaseGas), + "gasPrice": safeTransactionData.GasPrice, + "gasToken": safeTransactionData.GasToken, + "refundReceiver": safeTransactionData.RefundReceiver, + "nonce": fmt.Sprintf("%d", safeTransactionData.Nonce), + "safeTxHash": safeTxHash.Hex(), + "sender": key.Address.Hex(), + "signature": senderSignature, + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", txServiceBaseUrl), + } + + // Marshal the request body to JSON + jsonBody, err := json.Marshal(requestBody) + if err != nil { + return fmt.Errorf("failed to marshal request body: %v", err) + } + + // Send the request to the Safe Transaction Service + req, err := http.NewRequest("POST", txServiceBaseUrl, bytes.NewBuffer(jsonBody)) + if err != nil { + return fmt.Errorf("failed to create request: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + fmt.Println("Safe proposal created successfully") + return nil +} + +func CalculateSafeTxHash(safeAddress common.Address, txData SafeTransactionData, chainID *big.Int) (common.Hash, error) { + domainSeparator := apitypes.TypedDataDomain{ + ChainId: (*math.HexOrDecimal256)(chainID), + VerifyingContract: safeAddress.Hex(), + } + + typedData := apitypes.TypedData{ + Types: apitypes.Types{ + "EIP712Domain": []apitypes.Type{ + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "SafeTx": []apitypes.Type{ + {Name: "to", Type: "address"}, + {Name: "value", Type: "uint256"}, + {Name: "data", Type: "bytes"}, + {Name: "operation", Type: "uint8"}, + {Name: "safeTxGas", Type: "uint256"}, + {Name: "baseGas", Type: "uint256"}, + {Name: "gasPrice", Type: "uint256"}, + {Name: "gasToken", Type: "address"}, + {Name: "refundReceiver", Type: "address"}, + {Name: "nonce", Type: "uint256"}, + }, + }, + Domain: domainSeparator, + PrimaryType: "SafeTx", + Message: apitypes.TypedDataMessage{ + "to": txData.To, + "value": txData.Value, + "data": "0x" + txData.Data, + "operation": fmt.Sprintf("%d", txData.Operation), + "safeTxGas": fmt.Sprintf("%d", txData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", txData.BaseGas), + "gasPrice": txData.GasPrice, + "gasToken": txData.GasToken, + "refundReceiver": txData.RefundReceiver, + "nonce": fmt.Sprintf("%d", txData.Nonce), + }, + } + + typedDataHash, _, err := apitypes.TypedDataAndHash(typedData) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to hash typed data: %v", err) + } + + return common.BytesToHash(typedDataHash), nil +} ` // This template generates the handler for smart contract deployment. It is intended to be used with a @@ -1077,6 +1311,8 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint + var useSafe bool + var safeAddress, txServiceBaseUrl, factoryAddress string {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1091,6 +1327,25 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + + if factoryAddress == "" { + return fmt.Errorf("--factory-address not specified") + } + if !common.IsHexAddress(factoryAddress) { + return fmt.Errorf("--factory-address is not a valid Ethereum address") + } + } + {{range .DeployHandler.MethodArgs}} {{.PreRunE}} {{- end}} @@ -1122,6 +1377,31 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + if useSafe { + // Generate deploy bytecode with constructor arguments + deployBytecode, err := generate{{.StructName}}DeployBytecode( + {{- range .DeployHandler.MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return fmt.Errorf("failed to generate deploy bytecode: %v", err) + } + + // Create Safe proposal for deployment + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = DeployWithSafe(rpc, keyfile, password, common.HexToAddress(safeAddress), common.HexToAddress(factoryAddress), value, txServiceBaseUrl, deployBytecode) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for deployment created successfully") + return nil + } + address, deploymentTransaction, _, deploymentErr := {{.DeployHandler.MethodName}}( transactionOpts, client, @@ -1175,6 +1455,10 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&factoryAddress, "factory-address", "", "Address of the ImmutableCreate2Factory contract (required if --safe is set)") {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} @@ -1182,6 +1466,29 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { return cmd } + +func generate{{.StructName}}DeployBytecode( + {{- range .DeployHandler.MethodArgs}} + {{.CLIVar}} {{.CLIType}}, + {{- end}} +) ([]byte, error) { + abiPacked, err := {{.StructName}}MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get ABI: %v", err) + } + + constructorArguments, err := abiPacked.Pack("", + {{- range .DeployHandler.MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return nil, fmt.Errorf("failed to pack constructor arguments: %v", err) + } + + deployBytecode := append(common.FromHex({{.StructName}}MetaData.Bin), constructorArguments...) + return deployBytecode, nil +} {{end}} ` @@ -1281,131 +1588,173 @@ func {{.HandlerName}}() *cobra.Command { var TransactMethodCommandsTemplate string = `{{$structName := .StructName}} {{range .TransactHandlers}} func {{.HandlerName}}() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string - var gasLimit uint64 - var simulate bool - var timeout uint - var contractAddress common.Address - - {{range .MethodArgs}} - var {{.CLIVar}} {{.CLIType}} - {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} - {{- end}} - - cmd := &cobra.Command{ - Use: "{{(KebabCase .MethodName)}}", - Short: "Execute the {{.MethodName}} method on a {{$structName}} contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - {{range .MethodArgs}} - {{.PreRunE}} - {{- end}} - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - key, keyErr := KeyFromFile(keyfile, password) - if keyErr != nil { - return keyErr - } - - chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) - defer cancelChainIDCtx() - chainID, chainIDErr := client.ChainID(chainIDCtx) - if chainIDErr != nil { - return chainIDErr - } - - transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) - if transactionOptsErr != nil { - return transactionOptsErr - } - - SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) - - contract, contractErr := New{{$structName}}(contractAddress, client) - if contractErr != nil { - return contractErr - } - - session := {{$structName}}TransactorSession{ - Contract: &contract.{{$structName}}Transactor, - TransactOpts: *transactionOpts, - } - - transaction, transactionErr := session.{{.MethodName}}( - {{- range .MethodArgs}} - {{.CLIVar}}, - {{- end}} - ) - if transactionErr != nil { - return transactionErr - } - - cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) - if transactionOpts.NoSend { - estimationMessage := ethereum.CallMsg{ - From: transactionOpts.From, - To: &contractAddress, - Data: transaction.Data(), - } - - gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) - defer cancelGasEstimationCtx() - - gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) - if gasEstimateErr != nil { - return gasEstimateErr - } - - transactionBinary, transactionBinaryErr := transaction.MarshalBinary() - if transactionBinaryErr != nil { - return transactionBinaryErr + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string + + {{range .MethodArgs}} + var {{.CLIVar}} {{.CLIType}} + {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} + {{- end}} + + cmd := &cobra.Command{ + Use: "{{(KebabCase .MethodName)}}", + Short: "Execute the {{.MethodName}} method on a {{$structName}} contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + + {{range .MethodArgs}} + {{.PreRunE}} + {{- end}} + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := New{{$structName}}(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := {{$structName}}TransactorSession{ + Contract: &contract.{{$structName}}Transactor, + TransactOpts: *transactionOpts, + } + + if useSafe { + // Generate transaction data + transactionData, err := session.{{.MethodName}}( + {{range .MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) } - transactionBinaryHex := hex.EncodeToString(transactionBinary) - - cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) - } else { - cmd.Println("Transaction submitted") - } - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") - cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") - cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") - cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") - cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") - cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") - cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.{{.MethodName}}( + {{range .MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") - {{range .MethodArgs}} - cmd.Flags().{{.Flag}} - {{- end}} + {{range .MethodArgs}} + cmd.Flags().{{.Flag}} + {{- end}} - return cmd + return cmd } {{- end}} ` diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 7dd4604..dc06359 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -1,5 +1,5 @@ // This file was generated by seer: https://github.com/moonstream-to/seer. -// seer version: 0.1.19 +// seer version: 0.1.21 // seer command: seer evm generate --package main --cli --includemain --abi fixtures/OwnableERC721.json --bytecode fixtures/OwnableERC721.bin --struct OwnableERC721 --output examples/ownable-erc-721/OwnableERC721.go // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. @@ -7,8 +7,11 @@ package main import ( + "bytes" + "crypto/rand" "errors" "math/big" + "net/http" "strings" "context" @@ -19,9 +22,15 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/signer/core/apitypes" + "github.com/moonstream-to/seer/bindings/GnosisSafe" + "github.com/moonstream-to/seer/bindings/ImmutableCreate2Factory" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" // Reference imports to suppress errors if they are not otherwise used. "encoding/hex" + "encoding/json" "fmt" "os" "time" @@ -1300,6 +1309,8 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint + var useSafe bool + var safeAddress, txServiceBaseUrl string var name_0 string @@ -1316,6 +1327,18 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if ownerRaw == "" { return fmt.Errorf("--owner argument not specified") } else if !common.IsHexAddress(ownerRaw) { @@ -1350,6 +1373,27 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + if useSafe { + // Generate deploy bytecode with constructor arguments + deployBytecode, err := generateOwnableERC721DeployBytecode( + name_0, + symbol, + owner, + ) + if err != nil { + return fmt.Errorf("failed to generate deploy bytecode: %v", err) + } + + // Create Safe proposal for deployment + err = DeployWithSafe(rpc, keyfile, password, common.HexToAddress(safeAddress), common.HexToAddress(txServiceBaseUrl), transactionOpts.Value, txServiceBaseUrl, deployBytecode, key.Address) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for deployment created successfully") + return nil + } + address, deploymentTransaction, _, deploymentErr := DeployOwnableERC721( transactionOpts, client, @@ -1402,6 +1446,9 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&name_0, "name-0", "", "name-0 argument") cmd.Flags().StringVar(&symbol, "symbol", "", "symbol argument") @@ -1410,6 +1457,29 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { return cmd } +func generateOwnableERC721DeployBytecode( + name_0 string, + symbol string, + owner common.Address, +) ([]byte, error) { + abiPacked, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get ABI: %v", err) + } + + constructorArguments, err := abiPacked.Pack("", + name_0, + symbol, + owner, + ) + if err != nil { + return nil, fmt.Errorf("failed to pack constructor arguments: %v", err) + } + + deployBytecode := append(common.FromHex(OwnableERC721MetaData.Bin), constructorArguments...) + return deployBytecode, nil +} + func CreateBalanceOfCommand() *cobra.Command { var contractAddressRaw, rpc string var contractAddress common.Address @@ -2079,6 +2149,8 @@ func CreateApproveCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var to0 common.Address var to0Raw string @@ -2089,10 +2161,6 @@ func CreateApproveCommand() *cobra.Command { Use: "approve", Short: "Execute the Approve method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2100,6 +2168,22 @@ func CreateApproveCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if to0Raw == "" { return fmt.Errorf("--to-0 argument not specified") } else if !common.IsHexAddress(to0Raw) { @@ -2150,12 +2234,34 @@ func CreateApproveCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.Approve( + if useSafe { + // Generate transaction data + transactionData, err := session.Approve( + + to0, + tokenId, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.Approve( + to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2201,6 +2307,9 @@ func CreateApproveCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2213,6 +2322,8 @@ func CreateMintCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var to0 common.Address var to0Raw string @@ -2223,10 +2334,6 @@ func CreateMintCommand() *cobra.Command { Use: "mint", Short: "Execute the Mint method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2234,6 +2341,22 @@ func CreateMintCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if to0Raw == "" { return fmt.Errorf("--to-0 argument not specified") } else if !common.IsHexAddress(to0Raw) { @@ -2284,12 +2407,34 @@ func CreateMintCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.Mint( + if useSafe { + // Generate transaction data + transactionData, err := session.Mint( + + to0, + tokenId, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.Mint( + to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2335,6 +2480,9 @@ func CreateMintCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2347,15 +2495,13 @@ func CreateRenounceOwnershipCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string cmd := &cobra.Command{ Use: "renounce-ownership", Short: "Execute the RenounceOwnership method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2363,6 +2509,22 @@ func CreateRenounceOwnershipCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + return nil }, RunE: func(cmd *cobra.Command, args []string) error { @@ -2400,9 +2562,26 @@ func CreateRenounceOwnershipCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.RenounceOwnership() - if transactionErr != nil { - return transactionErr + if useSafe { + // Generate transaction data + transactionData, err := session.RenounceOwnership() + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.RenounceOwnership() + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2448,6 +2627,9 @@ func CreateRenounceOwnershipCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") return cmd } @@ -2457,6 +2639,8 @@ func CreateSafeTransferFromCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var from0 common.Address var from0Raw string @@ -2469,10 +2653,6 @@ func CreateSafeTransferFromCommand() *cobra.Command { Use: "safe-transfer-from", Short: "Execute the SafeTransferFrom method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2480,6 +2660,22 @@ func CreateSafeTransferFromCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if from0Raw == "" { return fmt.Errorf("--from-0 argument not specified") } else if !common.IsHexAddress(from0Raw) { @@ -2537,13 +2733,36 @@ func CreateSafeTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.SafeTransferFrom( + if useSafe { + // Generate transaction data + transactionData, err := session.SafeTransferFrom( + + from0, + to0, + tokenId, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.SafeTransferFrom( + from0, to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2589,6 +2808,9 @@ func CreateSafeTransferFromCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2602,6 +2824,8 @@ func CreateSafeTransferFrom0Command() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var from0 common.Address var from0Raw string @@ -2616,10 +2840,6 @@ func CreateSafeTransferFrom0Command() *cobra.Command { Use: "safe-transfer-from-0", Short: "Execute the SafeTransferFrom0 method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2627,6 +2847,22 @@ func CreateSafeTransferFrom0Command() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if from0Raw == "" { return fmt.Errorf("--from-0 argument not specified") } else if !common.IsHexAddress(from0Raw) { @@ -2694,14 +2930,38 @@ func CreateSafeTransferFrom0Command() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.SafeTransferFrom0( + if useSafe { + // Generate transaction data + transactionData, err := session.SafeTransferFrom0( + + from0, + to0, + tokenId, + data, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.SafeTransferFrom0( + from0, to0, tokenId, data, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2747,6 +3007,9 @@ func CreateSafeTransferFrom0Command() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2761,6 +3024,8 @@ func CreateSetApprovalForAllCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var operator common.Address var operatorRaw string @@ -2771,10 +3036,6 @@ func CreateSetApprovalForAllCommand() *cobra.Command { Use: "set-approval-for-all", Short: "Execute the SetApprovalForAll method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2782,6 +3043,22 @@ func CreateSetApprovalForAllCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if operatorRaw == "" { return fmt.Errorf("--operator argument not specified") } else if !common.IsHexAddress(operatorRaw) { @@ -2836,12 +3113,34 @@ func CreateSetApprovalForAllCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.SetApprovalForAll( + if useSafe { + // Generate transaction data + transactionData, err := session.SetApprovalForAll( + + operator, + approved, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.SetApprovalForAll( + operator, approved, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2887,6 +3186,9 @@ func CreateSetApprovalForAllCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&operatorRaw, "operator", "", "operator argument (common.Address)") cmd.Flags().StringVar(&approvedRaw, "approved", "", "approved argument (true, t, y, yes, 1 OR false, f, n, no, 0)") @@ -2899,6 +3201,8 @@ func CreateTransferFromCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var from0 common.Address var from0Raw string @@ -2911,10 +3215,6 @@ func CreateTransferFromCommand() *cobra.Command { Use: "transfer-from", Short: "Execute the TransferFrom method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2922,6 +3222,22 @@ func CreateTransferFromCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if from0Raw == "" { return fmt.Errorf("--from-0 argument not specified") } else if !common.IsHexAddress(from0Raw) { @@ -2979,13 +3295,36 @@ func CreateTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.TransferFrom( + if useSafe { + // Generate transaction data + transactionData, err := session.TransferFrom( + + from0, + to0, + tokenId, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.TransferFrom( + from0, to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -3031,6 +3370,9 @@ func CreateTransferFromCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3044,6 +3386,8 @@ func CreateTransferOwnershipCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var useSafe bool + var safeAddress, txServiceBaseUrl string var newOwner common.Address var newOwnerRaw string @@ -3052,10 +3396,6 @@ func CreateTransferOwnershipCommand() *cobra.Command { Use: "transfer-ownership", Short: "Execute the TransferOwnership method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -3063,6 +3403,22 @@ func CreateTransferOwnershipCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if useSafe { + if safeAddress == "" { + return fmt.Errorf("--safe-address not specified") + } + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe-address is not a valid Ethereum address") + } + if txServiceBaseUrl == "" { + return fmt.Errorf("--tx-service-base-url not specified") + } + } + if newOwnerRaw == "" { return fmt.Errorf("--new-owner argument not specified") } else if !common.IsHexAddress(newOwnerRaw) { @@ -3107,11 +3463,32 @@ func CreateTransferOwnershipCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.TransferOwnership( + if useSafe { + // Generate transaction data + transactionData, err := session.TransferOwnership( + + newOwner, + ) + if err != nil { + return fmt.Errorf("failed to generate transaction data: %v", err) + } + + // Create Safe proposal for transaction + err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + cmd.Println("Safe proposal for transaction created successfully") + return nil + } + + transaction, err := session.TransferOwnership( + newOwner, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -3157,6 +3534,9 @@ func CreateTransferOwnershipCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") + cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") + cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") @@ -3353,6 +3733,240 @@ func CreateOwnableERC721Command() *cobra.Command { return cmd } +// OperationType represents the type of operation for a Safe transaction +type OperationType uint8 + +const ( + Call OperationType = 0 + DelegateCall OperationType = 1 +) + +// String returns the string representation of the OperationType +func (o OperationType) String() string { + switch o { + case Call: + return "Call" + case DelegateCall: + return "DelegateCall" + default: + return "Unknown" + } +} + +// SafeTransactionData represents the data for a Safe transaction +type SafeTransactionData struct { + To string `json:"to"` + Value string `json:"value"` + Data string `json:"data"` + Operation OperationType `json:"operation"` + SafeTxGas uint64 `json:"safeTxGas"` + BaseGas uint64 `json:"baseGas"` + GasPrice string `json:"gasPrice"` + GasToken string `json:"gasToken"` + RefundReceiver string `json:"refundReceiver"` + Nonce uint64 `json:"nonce"` + SafeTxHash string `json:"safeTxHash"` + Sender string `json:"sender"` + Signature string `json:"signature"` + Origin string `json:"origin"` +} + +const ( + NativeTokenAddress = "0x0000000000000000000000000000000000000000" +) + +func DeployWithSafe(rpcURL string, keyfile string, password string, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, from common.Address) error { + // Generate salt + salt, err := GenerateProperSalt(from) + if err != nil { + return fmt.Errorf("failed to generate salt: %v", err) + } + + abi, err := ImmutableCreate2Factory.ImmutableCreate2FactoryMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + safeCreate2TxData, err := abi.Pack("safeCreate2", salt, deployBytecode) + if err != nil { + return fmt.Errorf("failed to pack safeCreate2 transaction: %v", err) + } + + return CreateSafeProposal(rpcURL, keyfile, password, safeAddress, factoryAddress, safeCreate2TxData, value, txServiceBaseUrl) +} + +func GenerateProperSalt(from common.Address) ([32]byte, error) { + var salt [32]byte + + // Copy the 'from' address to the first 20 bytes of the salt + copy(salt[:20], from[:]) + + // Generate random bytes for the remaining 12 bytes + _, err := rand.Read(salt[20:]) + if err != nil { + return [32]byte{}, fmt.Errorf("failed to generate random bytes: %w", err) + } + + return salt, nil +} + +func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string) error { + key, err := KeyFromFile(keyfile, password) + if err != nil { + return fmt.Errorf("failed to load key from file: %v", err) + } + + client, err := ethclient.Dial(rpcURL) + if err != nil { + return fmt.Errorf("failed to connect to the Ethereum client: %v", err) + } + + chainID, err := client.ChainID(context.Background()) + if err != nil { + return fmt.Errorf("failed to get chain ID: %v", err) + } + + // Create a new instance of the GnosisSafe contract + safeInstance, err := GnosisSafe.NewGnosisSafe(to, client) + if err != nil { + return fmt.Errorf("failed to create GnosisSafe instance: %v", err) + } + + // Fetch the current nonce from the Safe contract + nonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + + safeTransactionData := SafeTransactionData{ + To: to.Hex(), + Value: value.String(), + Data: common.Bytes2Hex(data), + Operation: Call, + SafeTxGas: 0, + BaseGas: 0, + GasPrice: "0", + GasToken: NativeTokenAddress, + RefundReceiver: NativeTokenAddress, // Changed to match the example + Nonce: nonce.Uint64(), // Use the fetched nonce + } + + // Calculate SafeTxHash + safeTxHash, err := CalculateSafeTxHash(to, safeTransactionData, chainID) + if err != nil { + return fmt.Errorf("failed to calculate SafeTxHash: %v", err) + } + + // Sign the SafeTxHash + signature, err := crypto.Sign(safeTxHash.Bytes(), key.PrivateKey) + if err != nil { + return fmt.Errorf("failed to sign SafeTxHash: %v", err) + } + + // Adjust V value for Ethereum's replay protection + signature[64] += 27 + + // Convert signature to hex + senderSignature := "0x" + common.Bytes2Hex(signature) + + // Prepare the request body + requestBody := map[string]interface{}{ + "to": safeTransactionData.To, + "value": safeTransactionData.Value, + "data": "0x" + safeTransactionData.Data, + "operation": int(safeTransactionData.Operation), + "safeTxGas": fmt.Sprintf("%d", safeTransactionData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", safeTransactionData.BaseGas), + "gasPrice": safeTransactionData.GasPrice, + "gasToken": safeTransactionData.GasToken, + "refundReceiver": safeTransactionData.RefundReceiver, + "nonce": fmt.Sprintf("%d", safeTransactionData.Nonce), + "safeTxHash": safeTxHash.Hex(), + "sender": key.Address.Hex(), + "signature": senderSignature, + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", txServiceBaseUrl), + } + + // Marshal the request body to JSON + jsonBody, err := json.Marshal(requestBody) + if err != nil { + return fmt.Errorf("failed to marshal request body: %v", err) + } + + // Send the request to the Safe Transaction Service + url := fmt.Sprintf(txServiceBaseUrl, chainID.String(), to.Hex()) + fmt.Println("url", url) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody)) + if err != nil { + return fmt.Errorf("failed to create request: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + fmt.Println("Safe proposal created successfully") + return nil +} + +func CalculateSafeTxHash(safeAddress common.Address, txData SafeTransactionData, chainID *big.Int) (common.Hash, error) { + domainSeparator := apitypes.TypedDataDomain{ + ChainId: (*math.HexOrDecimal256)(chainID), + VerifyingContract: safeAddress.Hex(), + } + + typedData := apitypes.TypedData{ + Types: apitypes.Types{ + "EIP712Domain": []apitypes.Type{ + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "SafeTx": []apitypes.Type{ + {Name: "to", Type: "address"}, + {Name: "value", Type: "uint256"}, + {Name: "data", Type: "bytes"}, + {Name: "operation", Type: "uint8"}, + {Name: "safeTxGas", Type: "uint256"}, + {Name: "baseGas", Type: "uint256"}, + {Name: "gasPrice", Type: "uint256"}, + {Name: "gasToken", Type: "address"}, + {Name: "refundReceiver", Type: "address"}, + {Name: "nonce", Type: "uint256"}, + }, + }, + Domain: domainSeparator, + PrimaryType: "SafeTx", + Message: apitypes.TypedDataMessage{ + "to": txData.To, + "value": txData.Value, + "data": "0x" + txData.Data, + "operation": fmt.Sprintf("%d", txData.Operation), + "safeTxGas": fmt.Sprintf("%d", txData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", txData.BaseGas), + "gasPrice": txData.GasPrice, + "gasToken": txData.GasToken, + "refundReceiver": txData.RefundReceiver, + "nonce": fmt.Sprintf("%d", txData.Nonce), + }, + } + + typedDataHash, _, err := apitypes.TypedDataAndHash(typedData) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to hash typed data: %v", err) + } + + return common.BytesToHash(typedDataHash), nil +} + func main() { command := CreateOwnableERC721Command() err := command.Execute() diff --git a/go.mod b/go.mod index 0c7c138..fb59b83 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/moonstream-to/seer -go 1.21 +go 1.22.0 + +toolchain go1.22.2 require ( cloud.google.com/go/storage v1.39.1 @@ -65,9 +67,9 @@ require ( golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect diff --git a/go.sum b/go.sum index 0ad15c5..cca9ddc 100644 --- a/go.sum +++ b/go.sum @@ -273,8 +273,8 @@ go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5Ukgg golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= @@ -282,8 +282,8 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -293,8 +293,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= @@ -302,8 +302,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -317,18 +317,18 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -338,8 +338,8 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= From bc30ab6fac29b02d671e617ad1a29e6b1990a4ff Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Tue, 24 Sep 2024 01:35:39 -0300 Subject: [PATCH 02/22] remove unused --- Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Makefile b/Makefile index e787b17..6398a9e 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,4 @@ examples/ownable-erc-721/OwnableERC721.go: rebuild ./seer evm generate --abi fixtures/OwnableERC721.json --bytecode fixtures/OwnableERC721.bin --cli --package main --struct OwnableERC721 --output examples/ownable-erc-721/OwnableERC721.go --includemain ownable-erc-721: examples/ownable-erc-721/OwnableERC721.go - go build ./examples/ownable-erc-721 - - - -token-sender: ./seer evm generate --package TokenSender --output ../../g7/protocol/bindings/TokenSender/TokenSender.go --hardhat ../../g7/protocol/web3/artifacts/contracts/faucet/TokenSender.sol/TokenSender.json --cli --struct TokenSender + go build ./examples/ownable-erc-721 \ No newline at end of file From 8e5c81b0c565867c570348d2212f7d7d7c2fe68e Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Tue, 24 Sep 2024 01:36:21 -0300 Subject: [PATCH 03/22] remove unused --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6398a9e..5e704c7 100644 --- a/Makefile +++ b/Makefile @@ -15,4 +15,4 @@ examples/ownable-erc-721/OwnableERC721.go: rebuild ./seer evm generate --abi fixtures/OwnableERC721.json --bytecode fixtures/OwnableERC721.bin --cli --package main --struct OwnableERC721 --output examples/ownable-erc-721/OwnableERC721.go --includemain ownable-erc-721: examples/ownable-erc-721/OwnableERC721.go - go build ./examples/ownable-erc-721 \ No newline at end of file + go build ./examples/ownable-erc-721 From 4a5cb107e6a754a324757639179b3a5133ef4290 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Wed, 25 Sep 2024 01:30:54 -0300 Subject: [PATCH 04/22] Feat: add safe operation flag and add default values for safe --- evm/generators.go | 137 ++++++++++++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 52 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index acf1ad8..ced5c3b 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1111,7 +1111,7 @@ const ( ) -func DeployWithSafe(rpcURL string, keyfile string, password string, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperation OperationType) error { // Generate salt salt, err := GenerateProperSalt(safeAddress) if err != nil { @@ -1128,7 +1128,7 @@ func DeployWithSafe(rpcURL string, keyfile string, password string, safeAddress return fmt.Errorf("failed to pack safeCreate2 transaction: %v", err) } - return CreateSafeProposal(rpcURL, keyfile, password, safeAddress, factoryAddress, safeCreate2TxData, value, txServiceBaseUrl) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreate2TxData, value, txServiceBaseUrl, OperationType(safeOperation)) } func GenerateProperSalt(from common.Address) ([32]byte, error) { @@ -1146,17 +1146,7 @@ func GenerateProperSalt(from common.Address) ([32]byte, error) { return salt, nil } -func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string) error { - key, err := KeyFromFile(keyfile, password) - if err != nil { - return fmt.Errorf("failed to load key from file: %v", err) - } - - client, err := ethclient.Dial(rpcURL) - if err != nil { - return fmt.Errorf("failed to connect to the Ethereum client: %v", err) - } - +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperation OperationType) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -1178,7 +1168,7 @@ func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddr To: to.Hex(), Value: value.String(), Data: common.Bytes2Hex(data), - Operation: Call, + Operation: safeOperation, SafeTxGas: 0, BaseGas: 0, GasPrice: "0", @@ -1311,9 +1301,8 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var useSafe bool - var safeAddress, txServiceBaseUrl, factoryAddress string - + var safeAddress, safeApi, safeCreate2 string + var safeOperation uint8 {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} @@ -1327,22 +1316,39 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if factoryAddress == "" { - return fmt.Errorf("--factory-address not specified") + if safeCreate2 == "" { + fmt.Println("--safe-create2 not specified, using default (0x0000000000FFe8B47B3e2130213B802212439497)") + safeCreate2 = "0x0000000000FFe8B47B3e2130213B802212439497" + } + if !common.IsHexAddress(safeCreate2) { + return fmt.Errorf("--safe-create2 is not a valid Ethereum address") } - if !common.IsHexAddress(factoryAddress) { - return fmt.Errorf("--factory-address is not a valid Ethereum address") + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -1377,7 +1383,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) - if useSafe { + if safeAddress != "" { // Generate deploy bytecode with constructor arguments deployBytecode, err := generate{{.StructName}}DeployBytecode( {{- range .DeployHandler.MethodArgs}} @@ -1393,7 +1399,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(rpc, keyfile, password, common.HexToAddress(safeAddress), common.HexToAddress(factoryAddress), value, txServiceBaseUrl, deployBytecode) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreate2), value, safeApi, deployBytecode, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1455,11 +1461,11 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") - cmd.Flags().StringVar(&factoryAddress, "factory-address", "", "Address of the ImmutableCreate2Factory contract (required if --safe is set)") - + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().StringVar(&safeCreate2, "safe-create2", "", "Address of the ImmutableCreate2Factory contract (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} {{- end}} @@ -1593,8 +1599,8 @@ func {{.HandlerName}}() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 {{range .MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1616,16 +1622,32 @@ func {{.HandlerName}}() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") - } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + return fmt.Errorf("--safe is not a valid Ethereum address") } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } } {{range .MethodArgs}} @@ -1669,15 +1691,26 @@ func {{.HandlerName}}() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.{{.MethodName}}( + abi, err := {{$structName}}MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Find the method in the ABI + method, exists := abi.Methods["{{.MethodName}}"] + if !exists { + return fmt.Errorf("method {{.MethodName}} not found in ABI") + } + + packedData, err := abi.Pack(method.Name, {{range .MethodArgs}} {{.CLIVar}}, {{- end}} ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction @@ -1685,7 +1718,7 @@ func {{.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), value, txServiceBaseUrl) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1746,9 +1779,9 @@ func {{.HandlerName}}() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") {{range .MethodArgs}} cmd.Flags().{{.Flag}} From 584d81d7aeeccc47688db9bc0db4f9705e32ea4f Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Wed, 25 Sep 2024 01:50:48 -0300 Subject: [PATCH 05/22] Fix: pack send data on safe flag --- evm/generators.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index ced5c3b..944e40c 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -822,6 +822,7 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, templateFuncs := map[string]any{ "KebabCase": strcase.ToKebab, "ScreamingSnake": strcase.ToScreamingSnake, + "ToLowerCamel": strcase.ToLowerCamel, } cliTemplate, cliTemplateParseErr := template.New("cli").Funcs(templateFuncs).Parse(CLICodeTemplate) @@ -1697,14 +1698,8 @@ func {{.HandlerName}}() *cobra.Command { if err != nil { return fmt.Errorf("failed to get ABI: %v", err) } - - // Find the method in the ABI - method, exists := abi.Methods["{{.MethodName}}"] - if !exists { - return fmt.Errorf("method {{.MethodName}} not found in ABI") - } - - packedData, err := abi.Pack(method.Name, + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("{{ToLowerCamel .MethodName}}", {{range .MethodArgs}} {{.CLIVar}}, {{- end}} From a8317b075e354eb3287c285b2623aefcdcc9eb2c Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Wed, 25 Sep 2024 19:43:04 -0300 Subject: [PATCH 06/22] Add Create Call --- bindings/CreateCall/CreateCall.go | 931 ++++++++++++++++++++++++++++++ evm/generators.go | 8 +- 2 files changed, 935 insertions(+), 4 deletions(-) create mode 100644 bindings/CreateCall/CreateCall.go diff --git a/bindings/CreateCall/CreateCall.go b/bindings/CreateCall/CreateCall.go new file mode 100644 index 0000000..e6d4f2c --- /dev/null +++ b/bindings/CreateCall/CreateCall.go @@ -0,0 +1,931 @@ +// This file was generated by seer: https://github.com/moonstream-to/seer. +// seer version: 0.1.20 +// seer command: seer evm generate --package Safe --cli --struct CreateCall --output bindings/CreateCall/CreateCall.go +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package Safe + +import ( + "errors" + "math/big" + "strings" + + "context" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + // Reference imports to suppress errors if they are not otherwise used. + "encoding/hex" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// CreateCallMetaData contains all meta data concerning the CreateCall contract. +var CreateCallMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractCreation\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"deploymentData\",\"type\":\"bytes\"}],\"name\":\"performCreate\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"deploymentData\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"performCreate2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061044b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634847be6f1461003b5780634c8c9ea114610134575b600080fd5b6101086004803603606081101561005157600080fd5b81019080803590602001909291908035906020019064010000000081111561007857600080fd5b82018360208201111561008a57600080fd5b803590602001918460018302840111640100000000831117156100ac57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050610223565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101f76004803603604081101561014a57600080fd5b81019080803590602001909291908035906020019064010000000081111561017157600080fd5b82018360208201111561018357600080fd5b803590602001918460018302840111640100000000831117156101a557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061031d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008183518460200186f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f436f756c64206e6f74206465706c6f7920636f6e74726163740000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51160405160405180910390a29392505050565b600081516020830184f09050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f436f756c64206e6f74206465706c6f7920636f6e74726163740000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51160405160405180910390a29291505056fea2646970667358221220153dfbb31f5824b1a17183b88443b5d0771b935e8acd92186d58555a02e4b41f64736f6c63430007060033", +} + +// CreateCallABI is the input ABI used to generate the binding from. +// Deprecated: Use CreateCallMetaData.ABI instead. +var CreateCallABI = CreateCallMetaData.ABI + +// CreateCallBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use CreateCallMetaData.Bin instead. +var CreateCallBin = CreateCallMetaData.Bin + +// DeployCreateCall deploys a new Ethereum contract, binding an instance of CreateCall to it. +func DeployCreateCall(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *CreateCall, error) { + parsed, err := CreateCallMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CreateCallBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CreateCall{CreateCallCaller: CreateCallCaller{contract: contract}, CreateCallTransactor: CreateCallTransactor{contract: contract}, CreateCallFilterer: CreateCallFilterer{contract: contract}}, nil +} + +// CreateCall is an auto generated Go binding around an Ethereum contract. +type CreateCall struct { + CreateCallCaller // Read-only binding to the contract + CreateCallTransactor // Write-only binding to the contract + CreateCallFilterer // Log filterer for contract events +} + +// CreateCallCaller is an auto generated read-only Go binding around an Ethereum contract. +type CreateCallCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// CreateCallTransactor is an auto generated write-only Go binding around an Ethereum contract. +type CreateCallTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// CreateCallFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type CreateCallFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// CreateCallSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type CreateCallSession struct { + Contract *CreateCall // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// CreateCallCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type CreateCallCallerSession struct { + Contract *CreateCallCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// CreateCallTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type CreateCallTransactorSession struct { + Contract *CreateCallTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// CreateCallRaw is an auto generated low-level Go binding around an Ethereum contract. +type CreateCallRaw struct { + Contract *CreateCall // Generic contract binding to access the raw methods on +} + +// CreateCallCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type CreateCallCallerRaw struct { + Contract *CreateCallCaller // Generic read-only contract binding to access the raw methods on +} + +// CreateCallTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type CreateCallTransactorRaw struct { + Contract *CreateCallTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewCreateCall creates a new instance of CreateCall, bound to a specific deployed contract. +func NewCreateCall(address common.Address, backend bind.ContractBackend) (*CreateCall, error) { + contract, err := bindCreateCall(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CreateCall{CreateCallCaller: CreateCallCaller{contract: contract}, CreateCallTransactor: CreateCallTransactor{contract: contract}, CreateCallFilterer: CreateCallFilterer{contract: contract}}, nil +} + +// NewCreateCallCaller creates a new read-only instance of CreateCall, bound to a specific deployed contract. +func NewCreateCallCaller(address common.Address, caller bind.ContractCaller) (*CreateCallCaller, error) { + contract, err := bindCreateCall(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CreateCallCaller{contract: contract}, nil +} + +// NewCreateCallTransactor creates a new write-only instance of CreateCall, bound to a specific deployed contract. +func NewCreateCallTransactor(address common.Address, transactor bind.ContractTransactor) (*CreateCallTransactor, error) { + contract, err := bindCreateCall(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CreateCallTransactor{contract: contract}, nil +} + +// NewCreateCallFilterer creates a new log filterer instance of CreateCall, bound to a specific deployed contract. +func NewCreateCallFilterer(address common.Address, filterer bind.ContractFilterer) (*CreateCallFilterer, error) { + contract, err := bindCreateCall(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CreateCallFilterer{contract: contract}, nil +} + +// bindCreateCall binds a generic wrapper to an already deployed contract. +func bindCreateCall(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CreateCallMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_CreateCall *CreateCallRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CreateCall.Contract.CreateCallCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_CreateCall *CreateCallRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CreateCall.Contract.CreateCallTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_CreateCall *CreateCallRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CreateCall.Contract.CreateCallTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_CreateCall *CreateCallCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CreateCall.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_CreateCall *CreateCallTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CreateCall.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_CreateCall *CreateCallTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CreateCall.Contract.contract.Transact(opts, method, params...) +} + +// PerformCreate is a paid mutator transaction binding the contract method 0x4c8c9ea1. +// +// Solidity: function performCreate(uint256 value, bytes deploymentData) returns(address newContract) +func (_CreateCall *CreateCallTransactor) PerformCreate(opts *bind.TransactOpts, value *big.Int, deploymentData []byte) (*types.Transaction, error) { + return _CreateCall.contract.Transact(opts, "performCreate", value, deploymentData) +} + +// PerformCreate is a paid mutator transaction binding the contract method 0x4c8c9ea1. +// +// Solidity: function performCreate(uint256 value, bytes deploymentData) returns(address newContract) +func (_CreateCall *CreateCallSession) PerformCreate(value *big.Int, deploymentData []byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate(&_CreateCall.TransactOpts, value, deploymentData) +} + +// PerformCreate is a paid mutator transaction binding the contract method 0x4c8c9ea1. +// +// Solidity: function performCreate(uint256 value, bytes deploymentData) returns(address newContract) +func (_CreateCall *CreateCallTransactorSession) PerformCreate(value *big.Int, deploymentData []byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate(&_CreateCall.TransactOpts, value, deploymentData) +} + +// PerformCreate2 is a paid mutator transaction binding the contract method 0x4847be6f. +// +// Solidity: function performCreate2(uint256 value, bytes deploymentData, bytes32 salt) returns(address newContract) +func (_CreateCall *CreateCallTransactor) PerformCreate2(opts *bind.TransactOpts, value *big.Int, deploymentData []byte, salt [32]byte) (*types.Transaction, error) { + return _CreateCall.contract.Transact(opts, "performCreate2", value, deploymentData, salt) +} + +// PerformCreate2 is a paid mutator transaction binding the contract method 0x4847be6f. +// +// Solidity: function performCreate2(uint256 value, bytes deploymentData, bytes32 salt) returns(address newContract) +func (_CreateCall *CreateCallSession) PerformCreate2(value *big.Int, deploymentData []byte, salt [32]byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate2(&_CreateCall.TransactOpts, value, deploymentData, salt) +} + +// PerformCreate2 is a paid mutator transaction binding the contract method 0x4847be6f. +// +// Solidity: function performCreate2(uint256 value, bytes deploymentData, bytes32 salt) returns(address newContract) +func (_CreateCall *CreateCallTransactorSession) PerformCreate2(value *big.Int, deploymentData []byte, salt [32]byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate2(&_CreateCall.TransactOpts, value, deploymentData, salt) +} + +// CreateCallContractCreationIterator is returned from FilterContractCreation and is used to iterate over the raw logs and unpacked data for ContractCreation events raised by the CreateCall contract. +type CreateCallContractCreationIterator struct { + Event *CreateCallContractCreation // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *CreateCallContractCreationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(CreateCallContractCreation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(CreateCallContractCreation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *CreateCallContractCreationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *CreateCallContractCreationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// CreateCallContractCreation represents a ContractCreation event raised by the CreateCall contract. +type CreateCallContractCreation struct { + NewContract common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterContractCreation is a free log retrieval operation binding the contract event 0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511. +// +// Solidity: event ContractCreation(address indexed newContract) +func (_CreateCall *CreateCallFilterer) FilterContractCreation(opts *bind.FilterOpts, newContract []common.Address) (*CreateCallContractCreationIterator, error) { + + var newContractRule []interface{} + for _, newContractItem := range newContract { + newContractRule = append(newContractRule, newContractItem) + } + + logs, sub, err := _CreateCall.contract.FilterLogs(opts, "ContractCreation", newContractRule) + if err != nil { + return nil, err + } + return &CreateCallContractCreationIterator{contract: _CreateCall.contract, event: "ContractCreation", logs: logs, sub: sub}, nil +} + +// WatchContractCreation is a free log subscription operation binding the contract event 0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511. +// +// Solidity: event ContractCreation(address indexed newContract) +func (_CreateCall *CreateCallFilterer) WatchContractCreation(opts *bind.WatchOpts, sink chan<- *CreateCallContractCreation, newContract []common.Address) (event.Subscription, error) { + + var newContractRule []interface{} + for _, newContractItem := range newContract { + newContractRule = append(newContractRule, newContractItem) + } + + logs, sub, err := _CreateCall.contract.WatchLogs(opts, "ContractCreation", newContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(CreateCallContractCreation) + if err := _CreateCall.contract.UnpackLog(event, "ContractCreation", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseContractCreation is a log parse operation binding the contract event 0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511. +// +// Solidity: event ContractCreation(address indexed newContract) +func (_CreateCall *CreateCallFilterer) ParseContractCreation(log types.Log) (*CreateCallContractCreation, error) { + event := new(CreateCallContractCreation) + if err := _CreateCall.contract.UnpackLog(event, "ContractCreation", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateCreateCallDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new CreateCall contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployCreateCall( + transactionOpts, + client, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + return cmd +} + +func CreatePerformCreateCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var value0 *big.Int + var value0Raw string + var deploymentData []byte + var deploymentDataRaw string + + cmd := &cobra.Command{ + Use: "perform-create", + Short: "Execute the PerformCreate method on a CreateCall contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var deploymentDataIntermediate []byte + + var deploymentDataIntermediateHexDecodeErr error + deploymentDataIntermediate, deploymentDataIntermediateHexDecodeErr = hex.DecodeString(deploymentDataRaw) + if deploymentDataIntermediateHexDecodeErr != nil { + return deploymentDataIntermediateHexDecodeErr + } + + copy(deploymentData[:], deploymentDataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewCreateCall(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := CreateCallTransactorSession{ + Contract: &contract.CreateCallTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.PerformCreate( + value0, + deploymentData, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&deploymentDataRaw, "deployment-data", "", "deployment-data argument ([]byte)") + + return cmd +} +func CreatePerformCreate2Command() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var value0 *big.Int + var value0Raw string + var deploymentData []byte + var deploymentDataRaw string + var salt [32]byte + var saltRaw string + + cmd := &cobra.Command{ + Use: "perform-create-2", + Short: "Execute the PerformCreate2 method on a CreateCall contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var deploymentDataIntermediate []byte + + var deploymentDataIntermediateHexDecodeErr error + deploymentDataIntermediate, deploymentDataIntermediateHexDecodeErr = hex.DecodeString(deploymentDataRaw) + if deploymentDataIntermediateHexDecodeErr != nil { + return deploymentDataIntermediateHexDecodeErr + } + + copy(deploymentData[:], deploymentDataIntermediate) + + var saltIntermediate []byte + + var saltIntermediateHexDecodeErr error + saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) + if saltIntermediateHexDecodeErr != nil { + return saltIntermediateHexDecodeErr + } + + copy(salt[:], saltIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewCreateCall(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := CreateCallTransactorSession{ + Contract: &contract.CreateCallTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.PerformCreate2( + value0, + deploymentData, + salt, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&deploymentDataRaw, "deployment-data", "", "deployment-data argument ([]byte)") + cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the CREATE_CALL_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the CREATE_CALL_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("CREATE_CALL_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateCreateCallCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-call", + Short: "Interact with the CreateCall contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployCreateCall := CreateCreateCallDeploymentCommand() + cmdDeployCreateCall.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployCreateCall) + + cmdTransactPerformCreate := CreatePerformCreateCommand() + cmdTransactPerformCreate.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactPerformCreate) + cmdTransactPerformCreate2 := CreatePerformCreate2Command() + cmdTransactPerformCreate2.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactPerformCreate2) + + return cmd +} diff --git a/evm/generators.go b/evm/generators.go index 944e40c..6dfc4cc 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1119,17 +1119,17 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to generate salt: %v", err) } - abi, err := ImmutableCreate2Factory.ImmutableCreate2FactoryMetaData.GetAbi() + abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) } - safeCreate2TxData, err := abi.Pack("safeCreate2", salt, deployBytecode) + safeCreate2TxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) if err != nil { - return fmt.Errorf("failed to pack safeCreate2 transaction: %v", err) + return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreate2TxData, value, txServiceBaseUrl, OperationType(safeOperation)) + return CreateSafeProposal(client, key, safeAddress, safeAddress, safeCreate2TxData, value, txServiceBaseUrl, OperationType(safeOperation)) } func GenerateProperSalt(from common.Address) ([32]byte, error) { From 0fca3182f40f3a089e902231c041b93e414b70da Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Wed, 25 Sep 2024 19:54:01 -0300 Subject: [PATCH 07/22] Add Create Call --- bindings/CreateCall/CreateCall.go | 4 ++-- evm/generators.go | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bindings/CreateCall/CreateCall.go b/bindings/CreateCall/CreateCall.go index e6d4f2c..6220e07 100644 --- a/bindings/CreateCall/CreateCall.go +++ b/bindings/CreateCall/CreateCall.go @@ -1,10 +1,10 @@ // This file was generated by seer: https://github.com/moonstream-to/seer. // seer version: 0.1.20 -// seer command: seer evm generate --package Safe --cli --struct CreateCall --output bindings/CreateCall/CreateCall.go +// seer command: seer evm generate --package CreateCall --cli --struct CreateCall --output bindings/CreateCall/CreateCall.go // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package Safe +package CreateCall import ( "errors" diff --git a/evm/generators.go b/evm/generators.go index 6dfc4cc..2d615c1 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -780,6 +780,8 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, // - github.com/ethereum/go-ethereum/accounts/keystore // - github.com/ethereum/go-ethereum/ethclient // - golang.org/x/term + // - github.com/moonstream-to/seer/bindings/GnosisSafe + // - github.com/moonstream-to/seer/bindings/CreateCall if t.Tok == token.IMPORT { t.Specs = append( t.Specs, @@ -793,6 +795,8 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/accounts/keystore"`}}, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/ethclient"`}}, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"golang.org/x/term"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/moonstream-to/seer/bindings/GnosisSafe"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/moonstream-to/seer/bindings/CreateCall"`}}, ) } return true From 667742d400ac7d47715d9c4bb5b79751ac0284c4 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Wed, 25 Sep 2024 23:32:42 -0300 Subject: [PATCH 08/22] Fix Create Call perform create2 --- evm/generators.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index 2d615c1..6844b9e 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1128,12 +1128,12 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to get ABI: %v", err) } - safeCreate2TxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) + safeCreateCallTxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) if err != nil { return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, safeAddress, safeCreate2TxData, value, txServiceBaseUrl, OperationType(safeOperation)) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, OperationType(safeOperation)) } func GenerateProperSalt(from common.Address) ([32]byte, error) { @@ -1306,7 +1306,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var safeAddress, safeApi, safeCreate2 string + var safeAddress, safeApi, safeCreateCall string var safeOperation uint8 {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1344,12 +1344,12 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if safeCreate2 == "" { - fmt.Println("--safe-create2 not specified, using default (0x0000000000FFe8B47B3e2130213B802212439497)") - safeCreate2 = "0x0000000000FFe8B47B3e2130213B802212439497" + if safeCreateCall == "" { + fmt.Println("--safe-create-call not specified, using default (0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)") + safeCreateCall = "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4" } - if !common.IsHexAddress(safeCreate2) { - return fmt.Errorf("--safe-create2 is not a valid Ethereum address") + if !common.IsHexAddress(safeCreateCall) { + return fmt.Errorf("--safe-create-call is not a valid Ethereum address") } if OperationType(safeOperation).String() == "Unknown" { @@ -1404,7 +1404,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreate2), value, safeApi, deployBytecode, OperationType(safeOperation)) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1468,8 +1468,8 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().StringVar(&safeCreate2, "safe-create2", "", "Address of the ImmutableCreate2Factory contract (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the ImmutableCreate2Factory contract (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} From e0ff92101cc5699195a89c1dee8d1b99cd5776e9 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Thu, 26 Sep 2024 00:04:36 -0300 Subject: [PATCH 09/22] Remove unused binding --- .../ImmutableCreate2Factory.go | 985 ------------------ 1 file changed, 985 deletions(-) delete mode 100644 bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go diff --git a/bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go b/bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go deleted file mode 100644 index 5b7c97e..0000000 --- a/bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go +++ /dev/null @@ -1,985 +0,0 @@ -// This file was generated by seer: https://github.com/moonstream-to/seer. -// seer version: 0.1.20 -// seer command: seer evm generate --package ImmutableCreate2Factory --cli --struct ImmutableCreate2Factory --output bindings/ImmutableCreate2Factory/ImmutableCreate2Factory.go -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package ImmutableCreate2Factory - -import ( - "errors" - "math/big" - "strings" - - "context" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" - - // Reference imports to suppress errors if they are not otherwise used. - "encoding/hex" - "fmt" - "os" - "time" - - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/spf13/cobra" - "golang.org/x/term" -) - -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// ImmutableCreate2FactoryMetaData contains all meta data concerning the ImmutableCreate2Factory contract. -var ImmutableCreate2FactoryMetaData = &bind.MetaData{ - ABI: "[{\"constant\":true,\"inputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"name\":\"hasBeenDeployed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initializationCode\",\"type\":\"bytes\"}],\"name\":\"safeCreate2\",\"outputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"findCreate2Address\",\"outputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\"},{\"name\":\"initCodeHash\",\"type\":\"bytes32\"}],\"name\":\"findCreate2AddressViaHash\",\"outputs\":[{\"name\":\"deploymentAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610833806100206000396000f3fe60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a7230582000b83240d6a142e399c7c44e5b6473d34001d171630229df870513bfb4740e2d64736f6c634300050a0032", -} - -// ImmutableCreate2FactoryABI is the input ABI used to generate the binding from. -// Deprecated: Use ImmutableCreate2FactoryMetaData.ABI instead. -var ImmutableCreate2FactoryABI = ImmutableCreate2FactoryMetaData.ABI - -// ImmutableCreate2FactoryBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ImmutableCreate2FactoryMetaData.Bin instead. -var ImmutableCreate2FactoryBin = ImmutableCreate2FactoryMetaData.Bin - -// DeployImmutableCreate2Factory deploys a new Ethereum contract, binding an instance of ImmutableCreate2Factory to it. -func DeployImmutableCreate2Factory(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ImmutableCreate2Factory, error) { - parsed, err := ImmutableCreate2FactoryMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ImmutableCreate2FactoryBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ImmutableCreate2Factory{ImmutableCreate2FactoryCaller: ImmutableCreate2FactoryCaller{contract: contract}, ImmutableCreate2FactoryTransactor: ImmutableCreate2FactoryTransactor{contract: contract}, ImmutableCreate2FactoryFilterer: ImmutableCreate2FactoryFilterer{contract: contract}}, nil -} - -// ImmutableCreate2Factory is an auto generated Go binding around an Ethereum contract. -type ImmutableCreate2Factory struct { - ImmutableCreate2FactoryCaller // Read-only binding to the contract - ImmutableCreate2FactoryTransactor // Write-only binding to the contract - ImmutableCreate2FactoryFilterer // Log filterer for contract events -} - -// ImmutableCreate2FactoryCaller is an auto generated read-only Go binding around an Ethereum contract. -type ImmutableCreate2FactoryCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ImmutableCreate2FactoryTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ImmutableCreate2FactoryTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ImmutableCreate2FactoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ImmutableCreate2FactoryFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ImmutableCreate2FactorySession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ImmutableCreate2FactorySession struct { - Contract *ImmutableCreate2Factory // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ImmutableCreate2FactoryCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ImmutableCreate2FactoryCallerSession struct { - Contract *ImmutableCreate2FactoryCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ImmutableCreate2FactoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ImmutableCreate2FactoryTransactorSession struct { - Contract *ImmutableCreate2FactoryTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ImmutableCreate2FactoryRaw is an auto generated low-level Go binding around an Ethereum contract. -type ImmutableCreate2FactoryRaw struct { - Contract *ImmutableCreate2Factory // Generic contract binding to access the raw methods on -} - -// ImmutableCreate2FactoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ImmutableCreate2FactoryCallerRaw struct { - Contract *ImmutableCreate2FactoryCaller // Generic read-only contract binding to access the raw methods on -} - -// ImmutableCreate2FactoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ImmutableCreate2FactoryTransactorRaw struct { - Contract *ImmutableCreate2FactoryTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewImmutableCreate2Factory creates a new instance of ImmutableCreate2Factory, bound to a specific deployed contract. -func NewImmutableCreate2Factory(address common.Address, backend bind.ContractBackend) (*ImmutableCreate2Factory, error) { - contract, err := bindImmutableCreate2Factory(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &ImmutableCreate2Factory{ImmutableCreate2FactoryCaller: ImmutableCreate2FactoryCaller{contract: contract}, ImmutableCreate2FactoryTransactor: ImmutableCreate2FactoryTransactor{contract: contract}, ImmutableCreate2FactoryFilterer: ImmutableCreate2FactoryFilterer{contract: contract}}, nil -} - -// NewImmutableCreate2FactoryCaller creates a new read-only instance of ImmutableCreate2Factory, bound to a specific deployed contract. -func NewImmutableCreate2FactoryCaller(address common.Address, caller bind.ContractCaller) (*ImmutableCreate2FactoryCaller, error) { - contract, err := bindImmutableCreate2Factory(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ImmutableCreate2FactoryCaller{contract: contract}, nil -} - -// NewImmutableCreate2FactoryTransactor creates a new write-only instance of ImmutableCreate2Factory, bound to a specific deployed contract. -func NewImmutableCreate2FactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*ImmutableCreate2FactoryTransactor, error) { - contract, err := bindImmutableCreate2Factory(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ImmutableCreate2FactoryTransactor{contract: contract}, nil -} - -// NewImmutableCreate2FactoryFilterer creates a new log filterer instance of ImmutableCreate2Factory, bound to a specific deployed contract. -func NewImmutableCreate2FactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*ImmutableCreate2FactoryFilterer, error) { - contract, err := bindImmutableCreate2Factory(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ImmutableCreate2FactoryFilterer{contract: contract}, nil -} - -// bindImmutableCreate2Factory binds a generic wrapper to an already deployed contract. -func bindImmutableCreate2Factory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ImmutableCreate2FactoryMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ImmutableCreate2Factory.Contract.ImmutableCreate2FactoryCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ImmutableCreate2Factory.Contract.ImmutableCreate2FactoryTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ImmutableCreate2Factory.Contract.ImmutableCreate2FactoryTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ImmutableCreate2Factory.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ImmutableCreate2Factory.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ImmutableCreate2Factory.Contract.contract.Transact(opts, method, params...) -} - -// FindCreate2Address is a free data retrieval call binding the contract method 0x85cf97ab. -// -// Solidity: function findCreate2Address(bytes32 salt, bytes initCode) view returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCaller) FindCreate2Address(opts *bind.CallOpts, salt [32]byte, initCode []byte) (common.Address, error) { - var out []interface{} - err := _ImmutableCreate2Factory.contract.Call(opts, &out, "findCreate2Address", salt, initCode) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// FindCreate2Address is a free data retrieval call binding the contract method 0x85cf97ab. -// -// Solidity: function findCreate2Address(bytes32 salt, bytes initCode) view returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) FindCreate2Address(salt [32]byte, initCode []byte) (common.Address, error) { - return _ImmutableCreate2Factory.Contract.FindCreate2Address(&_ImmutableCreate2Factory.CallOpts, salt, initCode) -} - -// FindCreate2Address is a free data retrieval call binding the contract method 0x85cf97ab. -// -// Solidity: function findCreate2Address(bytes32 salt, bytes initCode) view returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerSession) FindCreate2Address(salt [32]byte, initCode []byte) (common.Address, error) { - return _ImmutableCreate2Factory.Contract.FindCreate2Address(&_ImmutableCreate2Factory.CallOpts, salt, initCode) -} - -// FindCreate2AddressViaHash is a free data retrieval call binding the contract method 0xa49a7c90. -// -// Solidity: function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) view returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCaller) FindCreate2AddressViaHash(opts *bind.CallOpts, salt [32]byte, initCodeHash [32]byte) (common.Address, error) { - var out []interface{} - err := _ImmutableCreate2Factory.contract.Call(opts, &out, "findCreate2AddressViaHash", salt, initCodeHash) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// FindCreate2AddressViaHash is a free data retrieval call binding the contract method 0xa49a7c90. -// -// Solidity: function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) view returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) FindCreate2AddressViaHash(salt [32]byte, initCodeHash [32]byte) (common.Address, error) { - return _ImmutableCreate2Factory.Contract.FindCreate2AddressViaHash(&_ImmutableCreate2Factory.CallOpts, salt, initCodeHash) -} - -// FindCreate2AddressViaHash is a free data retrieval call binding the contract method 0xa49a7c90. -// -// Solidity: function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) view returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerSession) FindCreate2AddressViaHash(salt [32]byte, initCodeHash [32]byte) (common.Address, error) { - return _ImmutableCreate2Factory.Contract.FindCreate2AddressViaHash(&_ImmutableCreate2Factory.CallOpts, salt, initCodeHash) -} - -// HasBeenDeployed is a free data retrieval call binding the contract method 0x08508b8f. -// -// Solidity: function hasBeenDeployed(address deploymentAddress) view returns(bool) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCaller) HasBeenDeployed(opts *bind.CallOpts, deploymentAddress common.Address) (bool, error) { - var out []interface{} - err := _ImmutableCreate2Factory.contract.Call(opts, &out, "hasBeenDeployed", deploymentAddress) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// HasBeenDeployed is a free data retrieval call binding the contract method 0x08508b8f. -// -// Solidity: function hasBeenDeployed(address deploymentAddress) view returns(bool) -func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) HasBeenDeployed(deploymentAddress common.Address) (bool, error) { - return _ImmutableCreate2Factory.Contract.HasBeenDeployed(&_ImmutableCreate2Factory.CallOpts, deploymentAddress) -} - -// HasBeenDeployed is a free data retrieval call binding the contract method 0x08508b8f. -// -// Solidity: function hasBeenDeployed(address deploymentAddress) view returns(bool) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryCallerSession) HasBeenDeployed(deploymentAddress common.Address) (bool, error) { - return _ImmutableCreate2Factory.Contract.HasBeenDeployed(&_ImmutableCreate2Factory.CallOpts, deploymentAddress) -} - -// SafeCreate2 is a paid mutator transaction binding the contract method 0x64e03087. -// -// Solidity: function safeCreate2(bytes32 salt, bytes initializationCode) payable returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactor) SafeCreate2(opts *bind.TransactOpts, salt [32]byte, initializationCode []byte) (*types.Transaction, error) { - return _ImmutableCreate2Factory.contract.Transact(opts, "safeCreate2", salt, initializationCode) -} - -// SafeCreate2 is a paid mutator transaction binding the contract method 0x64e03087. -// -// Solidity: function safeCreate2(bytes32 salt, bytes initializationCode) payable returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactorySession) SafeCreate2(salt [32]byte, initializationCode []byte) (*types.Transaction, error) { - return _ImmutableCreate2Factory.Contract.SafeCreate2(&_ImmutableCreate2Factory.TransactOpts, salt, initializationCode) -} - -// SafeCreate2 is a paid mutator transaction binding the contract method 0x64e03087. -// -// Solidity: function safeCreate2(bytes32 salt, bytes initializationCode) payable returns(address deploymentAddress) -func (_ImmutableCreate2Factory *ImmutableCreate2FactoryTransactorSession) SafeCreate2(salt [32]byte, initializationCode []byte) (*types.Transaction, error) { - return _ImmutableCreate2Factory.Contract.SafeCreate2(&_ImmutableCreate2Factory.TransactOpts, salt, initializationCode) -} - -func CreateImmutableCreate2FactoryDeploymentCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string - var gasLimit uint64 - var simulate bool - var timeout uint - - cmd := &cobra.Command{ - Use: "deploy", - Short: "Deploy a new ImmutableCreate2Factory contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") - } - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - key, keyErr := KeyFromFile(keyfile, password) - if keyErr != nil { - return keyErr - } - - chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) - defer cancelChainIDCtx() - chainID, chainIDErr := client.ChainID(chainIDCtx) - if chainIDErr != nil { - return chainIDErr - } - - transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) - if transactionOptsErr != nil { - return transactionOptsErr - } - - SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) - - address, deploymentTransaction, _, deploymentErr := DeployImmutableCreate2Factory( - transactionOpts, - client, - ) - if deploymentErr != nil { - return deploymentErr - } - - cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) - if transactionOpts.NoSend { - estimationMessage := ethereum.CallMsg{ - From: transactionOpts.From, - Data: deploymentTransaction.Data(), - } - - gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) - defer cancelGasEstimationCtx() - - gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) - if gasEstimateErr != nil { - return gasEstimateErr - } - - transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() - if transactionBinaryErr != nil { - return transactionBinaryErr - } - transactionBinaryHex := hex.EncodeToString(transactionBinary) - - cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) - } else { - cmd.Println("Transaction submitted") - } - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") - cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") - cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") - cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") - cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") - cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") - cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - - return cmd -} - -func CreateFindCreate2AddressCommand() *cobra.Command { - var contractAddressRaw, rpc string - var contractAddress common.Address - var timeout uint - - var blockNumberRaw, fromAddressRaw string - var pending bool - - var salt [32]byte - var saltRaw string - var initCode []byte - var initCodeRaw string - - var capture0 common.Address - - cmd := &cobra.Command{ - Use: "find-create-2-address", - Short: "Call the FindCreate2Address view method on a ImmutableCreate2Factory contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - var saltIntermediate []byte - - var saltIntermediateHexDecodeErr error - saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) - if saltIntermediateHexDecodeErr != nil { - return saltIntermediateHexDecodeErr - } - - copy(salt[:], saltIntermediate) - - var initCodeIntermediate []byte - - var initCodeIntermediateHexDecodeErr error - initCodeIntermediate, initCodeIntermediateHexDecodeErr = hex.DecodeString(initCodeRaw) - if initCodeIntermediateHexDecodeErr != nil { - return initCodeIntermediateHexDecodeErr - } - - copy(initCode[:], initCodeIntermediate) - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) - if contractErr != nil { - return contractErr - } - - callOpts := bind.CallOpts{} - SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) - - session := ImmutableCreate2FactoryCallerSession{ - Contract: &contract.ImmutableCreate2FactoryCaller, - CallOpts: callOpts, - } - - var callErr error - capture0, callErr = session.FindCreate2Address( - salt, - initCode, - ) - if callErr != nil { - return callErr - } - - cmd.Printf("0: %s\n", capture0.Hex()) - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") - cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") - - cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") - cmd.Flags().StringVar(&initCodeRaw, "init-code", "", "init-code argument ([]byte)") - - return cmd -} -func CreateFindCreate2AddressViaHashCommand() *cobra.Command { - var contractAddressRaw, rpc string - var contractAddress common.Address - var timeout uint - - var blockNumberRaw, fromAddressRaw string - var pending bool - - var salt [32]byte - var saltRaw string - var initCodeHash [32]byte - var initCodeHashRaw string - - var capture0 common.Address - - cmd := &cobra.Command{ - Use: "find-create-2-address-via-hash", - Short: "Call the FindCreate2AddressViaHash view method on a ImmutableCreate2Factory contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - var saltIntermediate []byte - - var saltIntermediateHexDecodeErr error - saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) - if saltIntermediateHexDecodeErr != nil { - return saltIntermediateHexDecodeErr - } - - copy(salt[:], saltIntermediate) - - var initCodeHashIntermediate []byte - - var initCodeHashIntermediateHexDecodeErr error - initCodeHashIntermediate, initCodeHashIntermediateHexDecodeErr = hex.DecodeString(initCodeHashRaw) - if initCodeHashIntermediateHexDecodeErr != nil { - return initCodeHashIntermediateHexDecodeErr - } - - copy(initCodeHash[:], initCodeHashIntermediate) - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) - if contractErr != nil { - return contractErr - } - - callOpts := bind.CallOpts{} - SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) - - session := ImmutableCreate2FactoryCallerSession{ - Contract: &contract.ImmutableCreate2FactoryCaller, - CallOpts: callOpts, - } - - var callErr error - capture0, callErr = session.FindCreate2AddressViaHash( - salt, - initCodeHash, - ) - if callErr != nil { - return callErr - } - - cmd.Printf("0: %s\n", capture0.Hex()) - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") - cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") - - cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") - cmd.Flags().StringVar(&initCodeHashRaw, "init-code-hash", "", "init-code-hash argument ([32]byte)") - - return cmd -} -func CreateHasBeenDeployedCommand() *cobra.Command { - var contractAddressRaw, rpc string - var contractAddress common.Address - var timeout uint - - var blockNumberRaw, fromAddressRaw string - var pending bool - - var deploymentAddress common.Address - var deploymentAddressRaw string - - var capture0 bool - - cmd := &cobra.Command{ - Use: "has-been-deployed", - Short: "Call the HasBeenDeployed view method on a ImmutableCreate2Factory contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - if deploymentAddressRaw == "" { - return fmt.Errorf("--deployment-address argument not specified") - } else if !common.IsHexAddress(deploymentAddressRaw) { - return fmt.Errorf("--deployment-address argument is not a valid Ethereum address") - } - deploymentAddress = common.HexToAddress(deploymentAddressRaw) - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) - if contractErr != nil { - return contractErr - } - - callOpts := bind.CallOpts{} - SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) - - session := ImmutableCreate2FactoryCallerSession{ - Contract: &contract.ImmutableCreate2FactoryCaller, - CallOpts: callOpts, - } - - var callErr error - capture0, callErr = session.HasBeenDeployed( - deploymentAddress, - ) - if callErr != nil { - return callErr - } - - cmd.Printf("0: %t\n", capture0) - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") - cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") - - cmd.Flags().StringVar(&deploymentAddressRaw, "deployment-address", "", "deployment-address argument (common.Address)") - - return cmd -} - -func CreateSafeCreate2Command() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string - var gasLimit uint64 - var simulate bool - var timeout uint - var contractAddress common.Address - - var salt [32]byte - var saltRaw string - var initializationCode []byte - var initializationCodeRaw string - - cmd := &cobra.Command{ - Use: "safe-create-2", - Short: "Execute the SafeCreate2 method on a ImmutableCreate2Factory contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - var saltIntermediate []byte - - var saltIntermediateHexDecodeErr error - saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) - if saltIntermediateHexDecodeErr != nil { - return saltIntermediateHexDecodeErr - } - - copy(salt[:], saltIntermediate) - - var initializationCodeIntermediate []byte - - var initializationCodeIntermediateHexDecodeErr error - initializationCodeIntermediate, initializationCodeIntermediateHexDecodeErr = hex.DecodeString(initializationCodeRaw) - if initializationCodeIntermediateHexDecodeErr != nil { - return initializationCodeIntermediateHexDecodeErr - } - - copy(initializationCode[:], initializationCodeIntermediate) - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - key, keyErr := KeyFromFile(keyfile, password) - if keyErr != nil { - return keyErr - } - - chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) - defer cancelChainIDCtx() - chainID, chainIDErr := client.ChainID(chainIDCtx) - if chainIDErr != nil { - return chainIDErr - } - - transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) - if transactionOptsErr != nil { - return transactionOptsErr - } - - SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) - - contract, contractErr := NewImmutableCreate2Factory(contractAddress, client) - if contractErr != nil { - return contractErr - } - - session := ImmutableCreate2FactoryTransactorSession{ - Contract: &contract.ImmutableCreate2FactoryTransactor, - TransactOpts: *transactionOpts, - } - - transaction, transactionErr := session.SafeCreate2( - salt, - initializationCode, - ) - if transactionErr != nil { - return transactionErr - } - - cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) - if transactionOpts.NoSend { - estimationMessage := ethereum.CallMsg{ - From: transactionOpts.From, - To: &contractAddress, - Data: transaction.Data(), - } - - gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) - defer cancelGasEstimationCtx() - - gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) - if gasEstimateErr != nil { - return gasEstimateErr - } - - transactionBinary, transactionBinaryErr := transaction.MarshalBinary() - if transactionBinaryErr != nil { - return transactionBinaryErr - } - transactionBinaryHex := hex.EncodeToString(transactionBinary) - - cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) - } else { - cmd.Println("Transaction submitted") - } - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") - cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") - cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") - cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") - cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") - cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") - cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - - cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") - cmd.Flags().StringVar(&initializationCodeRaw, "initialization-code", "", "initialization-code argument ([]byte)") - - return cmd -} - -var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the IMMUTABLE_CREATE_2_FACTORY_RPC_URL environment variable") - -// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it -// attempts to read the RPC URL from the IMMUTABLE_CREATE_2_FACTORY_RPC_URL environment variable. If that is empty, -// too, then it returns an error. -func NewClient(rpcURL string) (*ethclient.Client, error) { - if rpcURL == "" { - rpcURL = os.Getenv("IMMUTABLE_CREATE_2_FACTORY_RPC_URL") - } - - if rpcURL == "" { - return nil, ErrNoRPCURL - } - - client, err := ethclient.Dial(rpcURL) - return client, err -} - -// Creates a new context to be used when interacting with the chain client. -func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { - baseCtx := context.Background() - parsedTimeout := time.Duration(timeout) * time.Second - ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) - return ctx, cancel -} - -// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. -func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { - key, err := keystore.DecryptKey(keystoreData, password) - return key, err -} - -// Loads a key from file, prompting the user for the password if it is not provided as a function argument. -func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { - var emptyKey *keystore.Key - keystoreContent, readErr := os.ReadFile(keystoreFile) - if readErr != nil { - return emptyKey, readErr - } - - // If password is "", prompt user for password. - if password == "" { - fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) - passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) - if inputErr != nil { - return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) - } - fmt.Print("\n") - password = string(passwordRaw) - } - - key, err := UnlockKeystore(keystoreContent, password) - return key, err -} - -// This method is used to set the parameters on a view call from command line arguments (represented mostly as -// strings). -func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { - if pending { - opts.Pending = true - } - - if fromAddress != "" { - opts.From = common.HexToAddress(fromAddress) - } - - if blockNumber != "" { - opts.BlockNumber = new(big.Int) - opts.BlockNumber.SetString(blockNumber, 0) - } -} - -// This method is used to set the parameters on a transaction from command line arguments (represented mostly as -// strings). -func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { - if nonce != "" { - opts.Nonce = new(big.Int) - opts.Nonce.SetString(nonce, 0) - } - - if value != "" { - opts.Value = new(big.Int) - opts.Value.SetString(value, 0) - } - - if gasPrice != "" { - opts.GasPrice = new(big.Int) - opts.GasPrice.SetString(gasPrice, 0) - } - - if maxFeePerGas != "" { - opts.GasFeeCap = new(big.Int) - opts.GasFeeCap.SetString(maxFeePerGas, 0) - } - - if maxPriorityFeePerGas != "" { - opts.GasTipCap = new(big.Int) - opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) - } - - if gasLimit != 0 { - opts.GasLimit = gasLimit - } - - opts.NoSend = noSend -} - -func CreateImmutableCreate2FactoryCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "immutable-create-2-factory", - Short: "Interact with the ImmutableCreate2Factory contract", - Run: func(cmd *cobra.Command, args []string) { - cmd.Help() - }, - } - - cmd.SetOut(os.Stdout) - - DeployGroup := &cobra.Group{ - ID: "deploy", Title: "Commands which deploy contracts", - } - cmd.AddGroup(DeployGroup) - ViewGroup := &cobra.Group{ - ID: "view", Title: "Commands which view contract state", - } - TransactGroup := &cobra.Group{ - ID: "transact", Title: "Commands which submit transactions", - } - cmd.AddGroup(ViewGroup, TransactGroup) - - cmdDeployImmutableCreate2Factory := CreateImmutableCreate2FactoryDeploymentCommand() - cmdDeployImmutableCreate2Factory.GroupID = DeployGroup.ID - cmd.AddCommand(cmdDeployImmutableCreate2Factory) - - cmdViewFindCreate2Address := CreateFindCreate2AddressCommand() - cmdViewFindCreate2Address.GroupID = ViewGroup.ID - cmd.AddCommand(cmdViewFindCreate2Address) - cmdViewFindCreate2AddressViaHash := CreateFindCreate2AddressViaHashCommand() - cmdViewFindCreate2AddressViaHash.GroupID = ViewGroup.ID - cmd.AddCommand(cmdViewFindCreate2AddressViaHash) - cmdViewHasBeenDeployed := CreateHasBeenDeployedCommand() - cmdViewHasBeenDeployed.GroupID = ViewGroup.ID - cmd.AddCommand(cmdViewHasBeenDeployed) - - cmdTransactSafeCreate2 := CreateSafeCreate2Command() - cmdTransactSafeCreate2.GroupID = TransactGroup.ID - cmd.AddCommand(cmdTransactSafeCreate2) - - return cmd -} From cf8d7467149d3fb9a0f8a0e8adae6ad45e554806 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Thu, 26 Sep 2024 00:05:29 -0300 Subject: [PATCH 10/22] Update flag description --- evm/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/generators.go b/evm/generators.go index 6844b9e..c223a86 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1468,7 +1468,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the ImmutableCreate2Factory contract (optional)") + cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") {{range .DeployHandler.MethodArgs}} From 4c5330e2c2cd13fdc201d19f5297a2b1d007b297 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Thu, 26 Sep 2024 10:38:21 -0300 Subject: [PATCH 11/22] Bump minor version --- examples/ownable-erc-721/OwnableERC721.go | 557 +++++++++++++++------- version/version.go | 2 +- 2 files changed, 388 insertions(+), 171 deletions(-) diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index dc06359..8581e14 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -1,5 +1,5 @@ // This file was generated by seer: https://github.com/moonstream-to/seer. -// seer version: 0.1.21 +// seer version: 0.1.22 // seer command: seer evm generate --package main --cli --includemain --abi fixtures/OwnableERC721.json --bytecode fixtures/OwnableERC721.bin --struct OwnableERC721 --output examples/ownable-erc-721/OwnableERC721.go // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. @@ -23,8 +23,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/signer/core/apitypes" - "github.com/moonstream-to/seer/bindings/GnosisSafe" - "github.com/moonstream-to/seer/bindings/ImmutableCreate2Factory" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" @@ -37,6 +35,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/ethclient" + "github.com/moonstream-to/seer/bindings/CreateCall" + "github.com/moonstream-to/seer/bindings/GnosisSafe" "github.com/spf13/cobra" "golang.org/x/term" ) @@ -1309,8 +1309,8 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi, safeCreateCall string + var safeOperation uint8 var name_0 string @@ -1327,15 +1327,39 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if safeCreateCall == "" { + fmt.Println("--safe-create-call not specified, using default (0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)") + safeCreateCall = "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4" + } + if !common.IsHexAddress(safeCreateCall) { + return fmt.Errorf("--safe-create-call is not a valid Ethereum address") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -1373,7 +1397,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) - if useSafe { + if safeAddress != "" { // Generate deploy bytecode with constructor arguments deployBytecode, err := generateOwnableERC721DeployBytecode( name_0, @@ -1385,7 +1409,11 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { } // Create Safe proposal for deployment - err = DeployWithSafe(rpc, keyfile, password, common.HexToAddress(safeAddress), common.HexToAddress(txServiceBaseUrl), transactionOpts.Value, txServiceBaseUrl, deployBytecode, key.Address) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1446,9 +1474,10 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") cmd.Flags().StringVar(&name_0, "name-0", "", "name-0 argument") cmd.Flags().StringVar(&symbol, "symbol", "", "symbol argument") @@ -2149,8 +2178,8 @@ func CreateApproveCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var to0 common.Address var to0Raw string @@ -2172,15 +2201,31 @@ func CreateApproveCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2234,19 +2279,28 @@ func CreateApproveCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.Approve( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("approve", to0, tokenId, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2307,9 +2361,9 @@ func CreateApproveCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2322,8 +2376,8 @@ func CreateMintCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var to0 common.Address var to0Raw string @@ -2345,15 +2399,31 @@ func CreateMintCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2407,19 +2477,28 @@ func CreateMintCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.Mint( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("mint", to0, tokenId, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2480,9 +2559,9 @@ func CreateMintCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2495,8 +2574,8 @@ func CreateRenounceOwnershipCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 cmd := &cobra.Command{ Use: "renounce-ownership", @@ -2513,15 +2592,31 @@ func CreateRenounceOwnershipCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2562,15 +2657,24 @@ func CreateRenounceOwnershipCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.RenounceOwnership() + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("renounceOwnership") if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2627,9 +2731,9 @@ func CreateRenounceOwnershipCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") return cmd } @@ -2639,8 +2743,8 @@ func CreateSafeTransferFromCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var from0 common.Address var from0Raw string @@ -2664,15 +2768,31 @@ func CreateSafeTransferFromCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2733,20 +2853,29 @@ func CreateSafeTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.SafeTransferFrom( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("safeTransferFrom", from0, to0, tokenId, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2808,9 +2937,9 @@ func CreateSafeTransferFromCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2824,8 +2953,8 @@ func CreateSafeTransferFrom0Command() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var from0 common.Address var from0Raw string @@ -2851,15 +2980,31 @@ func CreateSafeTransferFrom0Command() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2930,9 +3075,14 @@ func CreateSafeTransferFrom0Command() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.SafeTransferFrom0( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("safeTransferFrom0", from0, to0, @@ -2940,11 +3090,15 @@ func CreateSafeTransferFrom0Command() *cobra.Command { data, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3007,9 +3161,9 @@ func CreateSafeTransferFrom0Command() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3024,8 +3178,8 @@ func CreateSetApprovalForAllCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var operator common.Address var operatorRaw string @@ -3047,15 +3201,31 @@ func CreateSetApprovalForAllCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3113,19 +3283,28 @@ func CreateSetApprovalForAllCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.SetApprovalForAll( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("setApprovalForAll", operator, approved, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3186,9 +3365,9 @@ func CreateSetApprovalForAllCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&operatorRaw, "operator", "", "operator argument (common.Address)") cmd.Flags().StringVar(&approvedRaw, "approved", "", "approved argument (true, t, y, yes, 1 OR false, f, n, no, 0)") @@ -3201,8 +3380,8 @@ func CreateTransferFromCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var from0 common.Address var from0Raw string @@ -3226,15 +3405,31 @@ func CreateTransferFromCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3295,20 +3490,29 @@ func CreateTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.TransferFrom( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("transferFrom", from0, to0, tokenId, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3370,9 +3574,9 @@ func CreateTransferFromCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3386,8 +3590,8 @@ func CreateTransferOwnershipCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var useSafe bool - var safeAddress, txServiceBaseUrl string + var safeAddress, safeApi string + var safeOperation uint8 var newOwner common.Address var newOwnerRaw string @@ -3407,15 +3611,31 @@ func CreateTransferOwnershipCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } - if useSafe { - if safeAddress == "" { - return fmt.Errorf("--safe-address not specified") - } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { if !common.IsHexAddress(safeAddress) { - return fmt.Errorf("--safe-address is not a valid Ethereum address") + return fmt.Errorf("--safe is not a valid Ethereum address") } - if txServiceBaseUrl == "" { - return fmt.Errorf("--tx-service-base-url not specified") + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3463,18 +3683,27 @@ func CreateTransferOwnershipCommand() *cobra.Command { TransactOpts: *transactionOpts, } - if useSafe { + if safeAddress != "" { // Generate transaction data - transactionData, err := session.TransferOwnership( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name + packedData, err := abi.Pack("transferOwnership", newOwner, ) if err != nil { - return fmt.Errorf("failed to generate transaction data: %v", err) + return fmt.Errorf("failed to pack transaction data: %v", err) } // Create Safe proposal for transaction - err = CreateSafeProposal(rpc, keyfile, password, common.HexToAddress(safeAddress), contractAddress, transactionData.Data(), transactionOpts.Value, txServiceBaseUrl) + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3534,9 +3763,9 @@ func CreateTransferOwnershipCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().BoolVar(&useSafe, "safe", false, "Create a Safe proposal instead of directly executing the transaction") - cmd.Flags().StringVar(&safeAddress, "safe-address", "", "Address of the Safe contract (required if --safe is set)") - cmd.Flags().StringVar(&txServiceBaseUrl, "tx-service-base-url", "", "Base URL for the Safe Transaction Service (required if --safe is set)") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") @@ -3775,24 +4004,24 @@ const ( NativeTokenAddress = "0x0000000000000000000000000000000000000000" ) -func DeployWithSafe(rpcURL string, keyfile string, password string, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, from common.Address) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperation OperationType) error { // Generate salt - salt, err := GenerateProperSalt(from) + salt, err := GenerateProperSalt(safeAddress) if err != nil { return fmt.Errorf("failed to generate salt: %v", err) } - abi, err := ImmutableCreate2Factory.ImmutableCreate2FactoryMetaData.GetAbi() + abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) } - safeCreate2TxData, err := abi.Pack("safeCreate2", salt, deployBytecode) + safeCreateCallTxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) if err != nil { - return fmt.Errorf("failed to pack safeCreate2 transaction: %v", err) + return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(rpcURL, keyfile, password, safeAddress, factoryAddress, safeCreate2TxData, value, txServiceBaseUrl) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, OperationType(safeOperation)) } func GenerateProperSalt(from common.Address) ([32]byte, error) { @@ -3810,24 +4039,14 @@ func GenerateProperSalt(from common.Address) ([32]byte, error) { return salt, nil } -func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string) error { - key, err := KeyFromFile(keyfile, password) - if err != nil { - return fmt.Errorf("failed to load key from file: %v", err) - } - - client, err := ethclient.Dial(rpcURL) - if err != nil { - return fmt.Errorf("failed to connect to the Ethereum client: %v", err) - } - +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperation OperationType) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) } // Create a new instance of the GnosisSafe contract - safeInstance, err := GnosisSafe.NewGnosisSafe(to, client) + safeInstance, err := GnosisSafe.NewGnosisSafe(safeAddress, client) if err != nil { return fmt.Errorf("failed to create GnosisSafe instance: %v", err) } @@ -3842,17 +4061,17 @@ func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddr To: to.Hex(), Value: value.String(), Data: common.Bytes2Hex(data), - Operation: Call, + Operation: safeOperation, SafeTxGas: 0, BaseGas: 0, GasPrice: "0", GasToken: NativeTokenAddress, - RefundReceiver: NativeTokenAddress, // Changed to match the example - Nonce: nonce.Uint64(), // Use the fetched nonce + RefundReceiver: NativeTokenAddress, + Nonce: nonce.Uint64(), } // Calculate SafeTxHash - safeTxHash, err := CalculateSafeTxHash(to, safeTransactionData, chainID) + safeTxHash, err := CalculateSafeTxHash(safeAddress, safeTransactionData, chainID) if err != nil { return fmt.Errorf("failed to calculate SafeTxHash: %v", err) } @@ -3894,9 +4113,7 @@ func CreateSafeProposal(rpcURL string, keyfile string, password string, safeAddr } // Send the request to the Safe Transaction Service - url := fmt.Sprintf(txServiceBaseUrl, chainID.String(), to.Hex()) - fmt.Println("url", url) - req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody)) + req, err := http.NewRequest("POST", txServiceBaseUrl, bytes.NewBuffer(jsonBody)) if err != nil { return fmt.Errorf("failed to create request: %v", err) } diff --git a/version/version.go b/version/version.go index 6144365..b471766 100644 --- a/version/version.go +++ b/version/version.go @@ -1,3 +1,3 @@ package version -var SeerVersion string = "0.1.22" +var SeerVersion string = "0.2.21" From 11018a1bc7aa85089102bb6225216f93aa948872 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Thu, 26 Sep 2024 22:07:03 -0300 Subject: [PATCH 12/22] Remove duplicated log --- evm/generators.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index c223a86..dac136c 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1409,7 +1409,6 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for deployment created successfully") return nil } @@ -1722,7 +1721,6 @@ func {{.HandlerName}}() *cobra.Command { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } From 2e2398ccccf364e8cc8dc2e391c59ea170a4f4c4 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 16:04:41 -0300 Subject: [PATCH 13/22] PR fixes --- evm/generators.go | 45 ++++---- examples/ownable-erc-721/OwnableERC721.go | 133 ++++++++++------------ go.mod | 22 ++-- go.sum | 100 ++++++++-------- version/version.go | 2 +- 5 files changed, 148 insertions(+), 154 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index dac136c..31063e0 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -782,6 +782,8 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, // - golang.org/x/term // - github.com/moonstream-to/seer/bindings/GnosisSafe // - github.com/moonstream-to/seer/bindings/CreateCall + // - github.com/ethereum/go-ethereum/common/math + // - github.com/ethereum/go-ethereum/crypto if t.Tok == token.IMPORT { t.Specs = append( t.Specs, @@ -913,8 +915,7 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, code = string(generatedCode) } - codeImportsFixed := strings.ReplaceAll(code, "github.com/quan8/go-ethereum", "github.com/ethereum/go-ethereum") - return codeImportsFixed, nil + return code, nil } // This template is used to generate the skeleton of the CLI, along with all utility methods that can be @@ -1073,16 +1074,16 @@ func Create{{.StructName}}Command() *cobra.Command { return cmd } -// OperationType represents the type of operation for a Safe transaction -type OperationType uint8 +// SafeOperationType represents the type of operation for a Safe transaction +type SafeOperationType uint8 const ( - Call OperationType = 0 - DelegateCall OperationType = 1 + Call SafeOperationType = 0 + DelegateCall SafeOperationType = 1 ) -// String returns the string representation of the OperationType -func (o OperationType) String() string { +// String returns the string representation of the SafeOperationType +func (o SafeOperationType) String() string { switch o { case Call: return "Call" @@ -1098,7 +1099,7 @@ type SafeTransactionData struct { To string ` + "`" + `json:"to"` + "`" + ` Value string ` + "`" + `json:"value"` + "`" + ` Data string ` + "`" + `json:"data"` + "`" + ` - Operation OperationType ` + "`" + `json:"operation"` + "`" + ` + Operation SafeOperationType ` + "`" + `json:"operation"` + "`" + ` SafeTxGas uint64 ` + "`" + `json:"safeTxGas"` + "`" + ` BaseGas uint64 ` + "`" + `json:"baseGas"` + "`" + ` GasPrice string ` + "`" + `json:"gasPrice"` + "`" + ` @@ -1116,7 +1117,7 @@ const ( ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperation OperationType) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperationType SafeOperationType) error { // Generate salt salt, err := GenerateProperSalt(safeAddress) if err != nil { @@ -1133,7 +1134,7 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, OperationType(safeOperation)) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, SafeOperationType(safeOperationType)) } func GenerateProperSalt(from common.Address) ([32]byte, error) { @@ -1151,7 +1152,7 @@ func GenerateProperSalt(from common.Address) ([32]byte, error) { return salt, nil } -func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperation OperationType) error { +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperationType SafeOperationType) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -1173,7 +1174,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress To: to.Hex(), Value: value.String(), Data: common.Bytes2Hex(data), - Operation: safeOperation, + Operation: safeOperationType, SafeTxGas: 0, BaseGas: 0, GasPrice: "0", @@ -1307,7 +1308,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var simulate bool var timeout uint var safeAddress, safeApi, safeCreateCall string - var safeOperation uint8 + var safeOperationType uint8 {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} @@ -1340,7 +1341,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -1352,7 +1353,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { return fmt.Errorf("--safe-create-call is not a valid Ethereum address") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -1404,7 +1405,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, OperationType(safeOperation)) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1468,7 +1469,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} @@ -1604,7 +1605,7 @@ func {{.HandlerName}}() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 {{range .MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1649,7 +1650,7 @@ func {{.HandlerName}}() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -1716,7 +1717,7 @@ func {{.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1778,7 +1779,7 @@ func {{.HandlerName}}() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") {{range .MethodArgs}} cmd.Flags().{{.Flag}} diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 8581e14..60489ee 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -1,5 +1,5 @@ // This file was generated by seer: https://github.com/moonstream-to/seer. -// seer version: 0.1.22 +// seer version: 0.2.0 // seer command: seer evm generate --package main --cli --includemain --abi fixtures/OwnableERC721.json --bytecode fixtures/OwnableERC721.bin --struct OwnableERC721 --output examples/ownable-erc-721/OwnableERC721.go // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. @@ -1310,7 +1310,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var simulate bool var timeout uint var safeAddress, safeApi, safeCreateCall string - var safeOperation uint8 + var safeOperationType uint8 var name_0 string @@ -1346,7 +1346,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -1358,7 +1358,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { return fmt.Errorf("--safe-create-call is not a valid Ethereum address") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -1413,12 +1413,11 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, OperationType(safeOperation)) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for deployment created successfully") return nil } @@ -1477,7 +1476,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") cmd.Flags().StringVar(&name_0, "name-0", "", "name-0 argument") cmd.Flags().StringVar(&symbol, "symbol", "", "symbol argument") @@ -2179,7 +2178,7 @@ func CreateApproveCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var to0 common.Address var to0Raw string @@ -2224,7 +2223,7 @@ func CreateApproveCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2300,12 +2299,11 @@ func CreateApproveCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -2363,7 +2361,7 @@ func CreateApproveCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2377,7 +2375,7 @@ func CreateMintCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var to0 common.Address var to0Raw string @@ -2422,7 +2420,7 @@ func CreateMintCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2498,12 +2496,11 @@ func CreateMintCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -2561,7 +2558,7 @@ func CreateMintCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2575,7 +2572,7 @@ func CreateRenounceOwnershipCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 cmd := &cobra.Command{ Use: "renounce-ownership", @@ -2615,7 +2612,7 @@ func CreateRenounceOwnershipCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2674,12 +2671,11 @@ func CreateRenounceOwnershipCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -2733,7 +2729,7 @@ func CreateRenounceOwnershipCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") return cmd } @@ -2744,7 +2740,7 @@ func CreateSafeTransferFromCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var from0 common.Address var from0Raw string @@ -2791,7 +2787,7 @@ func CreateSafeTransferFromCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -2875,12 +2871,11 @@ func CreateSafeTransferFromCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -2939,7 +2934,7 @@ func CreateSafeTransferFromCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2954,7 +2949,7 @@ func CreateSafeTransferFrom0Command() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var from0 common.Address var from0Raw string @@ -3003,7 +2998,7 @@ func CreateSafeTransferFrom0Command() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3098,12 +3093,11 @@ func CreateSafeTransferFrom0Command() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -3163,7 +3157,7 @@ func CreateSafeTransferFrom0Command() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3179,7 +3173,7 @@ func CreateSetApprovalForAllCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var operator common.Address var operatorRaw string @@ -3224,7 +3218,7 @@ func CreateSetApprovalForAllCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3304,12 +3298,11 @@ func CreateSetApprovalForAllCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -3367,7 +3360,7 @@ func CreateSetApprovalForAllCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&operatorRaw, "operator", "", "operator argument (common.Address)") cmd.Flags().StringVar(&approvedRaw, "approved", "", "approved argument (true, t, y, yes, 1 OR false, f, n, no, 0)") @@ -3381,7 +3374,7 @@ func CreateTransferFromCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var from0 common.Address var from0Raw string @@ -3428,7 +3421,7 @@ func CreateTransferFromCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3512,12 +3505,11 @@ func CreateTransferFromCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -3576,7 +3568,7 @@ func CreateTransferFromCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3591,7 +3583,7 @@ func CreateTransferOwnershipCommand() *cobra.Command { var timeout uint var contractAddress common.Address var safeAddress, safeApi string - var safeOperation uint8 + var safeOperationType uint8 var newOwner common.Address var newOwnerRaw string @@ -3634,7 +3626,7 @@ func CreateTransferOwnershipCommand() *cobra.Command { fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - if OperationType(safeOperation).String() == "Unknown" { + if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } } @@ -3703,12 +3695,11 @@ func CreateTransferOwnershipCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, OperationType(safeOperation)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } - cmd.Println("Safe proposal for transaction created successfully") return nil } @@ -3765,7 +3756,7 @@ func CreateTransferOwnershipCommand() *cobra.Command { cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - cmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") @@ -3962,16 +3953,16 @@ func CreateOwnableERC721Command() *cobra.Command { return cmd } -// OperationType represents the type of operation for a Safe transaction -type OperationType uint8 +// SafeOperationType represents the type of operation for a Safe transaction +type SafeOperationType uint8 const ( - Call OperationType = 0 - DelegateCall OperationType = 1 + Call SafeOperationType = 0 + DelegateCall SafeOperationType = 1 ) -// String returns the string representation of the OperationType -func (o OperationType) String() string { +// String returns the string representation of the SafeOperationType +func (o SafeOperationType) String() string { switch o { case Call: return "Call" @@ -3984,27 +3975,27 @@ func (o OperationType) String() string { // SafeTransactionData represents the data for a Safe transaction type SafeTransactionData struct { - To string `json:"to"` - Value string `json:"value"` - Data string `json:"data"` - Operation OperationType `json:"operation"` - SafeTxGas uint64 `json:"safeTxGas"` - BaseGas uint64 `json:"baseGas"` - GasPrice string `json:"gasPrice"` - GasToken string `json:"gasToken"` - RefundReceiver string `json:"refundReceiver"` - Nonce uint64 `json:"nonce"` - SafeTxHash string `json:"safeTxHash"` - Sender string `json:"sender"` - Signature string `json:"signature"` - Origin string `json:"origin"` + To string `json:"to"` + Value string `json:"value"` + Data string `json:"data"` + Operation SafeOperationType `json:"operation"` + SafeTxGas uint64 `json:"safeTxGas"` + BaseGas uint64 `json:"baseGas"` + GasPrice string `json:"gasPrice"` + GasToken string `json:"gasToken"` + RefundReceiver string `json:"refundReceiver"` + Nonce uint64 `json:"nonce"` + SafeTxHash string `json:"safeTxHash"` + Sender string `json:"sender"` + Signature string `json:"signature"` + Origin string `json:"origin"` } const ( NativeTokenAddress = "0x0000000000000000000000000000000000000000" ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperation OperationType) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperationType SafeOperationType) error { // Generate salt salt, err := GenerateProperSalt(safeAddress) if err != nil { @@ -4021,7 +4012,7 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, OperationType(safeOperation)) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, SafeOperationType(safeOperationType)) } func GenerateProperSalt(from common.Address) ([32]byte, error) { @@ -4039,7 +4030,7 @@ func GenerateProperSalt(from common.Address) ([32]byte, error) { return salt, nil } -func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperation OperationType) error { +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperationType SafeOperationType) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -4061,7 +4052,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress To: to.Hex(), Value: value.String(), Data: common.Bytes2Hex(data), - Operation: safeOperation, + Operation: safeOperationType, SafeTxGas: 0, BaseGas: 0, GasPrice: "0", diff --git a/go.mod b/go.mod index fb59b83..4b6f090 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.22.2 require ( cloud.google.com/go/storage v1.39.1 github.com/aws/aws-sdk-go v1.51.4 - github.com/ethereum/go-ethereum v1.13.11 + github.com/ethereum/go-ethereum v1.14.10 github.com/google/uuid v1.6.0 github.com/iancoleman/strcase v0.3.0 github.com/jackc/pgx/v5 v5.5.3 @@ -16,7 +16,7 @@ require ( golang.org/x/term v0.17.0 golang.org/x/tools v0.15.0 google.golang.org/api v0.167.0 - google.golang.org/protobuf v1.34.1 + google.golang.org/protobuf v1.34.2 ) require ( @@ -24,16 +24,18 @@ require ( cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.6 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -45,7 +47,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect - github.com/holiman/uint256 v1.2.4 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect @@ -54,7 +56,7 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect go.opencensus.io v0.24.0 // indirect diff --git a/go.sum b/go.sum index cca9ddc..1eb541b 100644 --- a/go.sum +++ b/go.sum @@ -12,41 +12,41 @@ cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OL github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= -github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/aws/aws-sdk-go v1.51.4 h1:yOVfGhRJyReBrACK0alLosJl8iXhWkNY1vrePYmhHdw= github.com/aws/aws-sdk-go v1.51.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= -github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -55,15 +55,15 @@ github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJ github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= -github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= -github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= @@ -74,20 +74,20 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= -github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= -github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.11 h1:b51Dsm+rEg7anFRUMGB8hODXHvNfcRKzz9vcj8wSdUs= -github.com/ethereum/go-ethereum v1.13.11/go.mod h1:gFtlVORuUcT+UUIcJ/veCNjkuOSujCi338uSHJrYAew= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.10 h1:kC24WjYeRjDy86LVo6MfF5Xs7nnUu+XG4AjaYIaZYko= +github.com/ethereum/go-ethereum v1.14.10/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -149,12 +149,12 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -175,8 +175,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -187,8 +187,8 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= @@ -239,10 +239,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -377,11 +377,11 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/version/version.go b/version/version.go index b471766..0589ddd 100644 --- a/version/version.go +++ b/version/version.go @@ -1,3 +1,3 @@ package version -var SeerVersion string = "0.2.21" +var SeerVersion string = "0.2.0" From b6e45de23826fbf460165c399b7c579fe6d60673 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 16:18:16 -0300 Subject: [PATCH 14/22] PR fixes --- evm/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/generators.go b/evm/generators.go index 31063e0..e0c3c5e 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1646,7 +1646,7 @@ func {{.HandlerName}}() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } From 01a6b7935b7e9b792537a324af9eb447f1e41fe0 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 19:30:11 -0300 Subject: [PATCH 15/22] chore: update readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d6cb576..3134793 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,12 @@ Commands which submit transactions transfer-from Execute the TransferFrom method on a OwnableERC721 contract transfer-ownership Execute the TransferOwnership method on a OwnableERC721 contract +Commands which propose transactions to Safe + safe Safe address to propose transactions to + safe-api Override default Safe API URL (default "https://safe-client.safe.global/v1/chains/${CHAIN_ID}/transactions/${SAFE_ADDRESS}/propose") + safe-operation Type of operation to propose: 0 (Call) or 1 (DelegateCall) (default 0 for deployment and 1 for function calls) + safe-create-call Address of the contract to deploy if the operation is a deployment (default "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4") + Additional Commands: completion Generate the autocompletion script for the specified shell help Help about any command From 4a9e16a35771d06c7c0c6dd5d725f2b44cd5cc26 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 19:48:36 -0300 Subject: [PATCH 16/22] refactor: require salt for deployment --- evm/generators.go | 43 ++++++---------- examples/ownable-erc-721/OwnableERC721.go | 63 +++++++++-------------- 2 files changed, 39 insertions(+), 67 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index e0c3c5e..3adf631 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1117,13 +1117,7 @@ const ( ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperationType SafeOperationType) error { - // Generate salt - salt, err := GenerateProperSalt(safeAddress) - if err != nil { - return fmt.Errorf("failed to generate salt: %v", err) - } - +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) @@ -1134,25 +1128,10 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, SafeOperationType(safeOperationType)) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType)) } -func GenerateProperSalt(from common.Address) ([32]byte, error) { - var salt [32]byte - - // Copy the 'from' address to the first 20 bytes of the salt - copy(salt[:20], from[:]) - - // Generate random bytes for the remaining 12 bytes - _, err := rand.Read(salt[20:]) - if err != nil { - return [32]byte{}, fmt.Errorf("failed to generate random bytes: %w", err) - } - - return salt, nil -} - -func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperationType SafeOperationType) error { +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -1216,7 +1195,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress "safeTxHash": safeTxHash.Hex(), "sender": key.Address.Hex(), "signature": senderSignature, - "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", txServiceBaseUrl), + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", safeApi), } // Marshal the request body to JSON @@ -1226,7 +1205,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress } // Send the request to the Safe Transaction Service - req, err := http.NewRequest("POST", txServiceBaseUrl, bytes.NewBuffer(jsonBody)) + req, err := http.NewRequest("POST", safeApi, bytes.NewBuffer(jsonBody)) if err != nil { return fmt.Errorf("failed to create request: %v", err) } @@ -1307,8 +1286,10 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var safeAddress, safeApi, safeCreateCall string + var safeAddress, safeApi, safeCreateCall, safeSaltRaw string var safeOperationType uint8 + var safeSalt [32]byte + {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} @@ -1356,6 +1337,11 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeSaltRaw == "" { + return fmt.Errorf("--safe-salt not specified") + } + safeSalt = common.Hex2Bytes(safeSaltRaw) } {{range .DeployHandler.MethodArgs}} @@ -1405,7 +1391,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType)) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), safeSalt) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1470,6 +1456,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().StringVar(&safeSaltRaw, "safe-salt", "", "Salt to use for the Safe transaction") {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 60489ee..5f995e1 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -8,7 +8,6 @@ package main import ( "bytes" - "crypto/rand" "errors" "math/big" "net/http" @@ -23,8 +22,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/signer/core/apitypes" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" + "github.com/quan8/go-ethereum/common/math" + "github.com/quan8/go-ethereum/crypto" // Reference imports to suppress errors if they are not otherwise used. "encoding/hex" @@ -1309,8 +1308,9 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var safeAddress, safeApi, safeCreateCall string + var safeAddress, safeApi, safeCreateCall, safeSaltRaw string var safeOperationType uint8 + var safeSalt [32]byte var name_0 string @@ -1361,6 +1361,11 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeSaltRaw == "" { + return fmt.Errorf("--safe-salt not specified") + } + safeSalt = common.Hex2Bytes(safeSaltRaw) } if ownerRaw == "" { @@ -1413,7 +1418,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType)) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), safeSalt) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1477,6 +1482,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().StringVar(&safeSaltRaw, "safe-salt", "", "Salt to use for the Safe transaction") cmd.Flags().StringVar(&name_0, "name-0", "", "name-0 argument") cmd.Flags().StringVar(&symbol, "symbol", "", "symbol argument") @@ -2219,7 +2225,7 @@ func CreateApproveCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -2416,7 +2422,7 @@ func CreateMintCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -2608,7 +2614,7 @@ func CreateRenounceOwnershipCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -2783,7 +2789,7 @@ func CreateSafeTransferFromCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -2994,7 +3000,7 @@ func CreateSafeTransferFrom0Command() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -3214,7 +3220,7 @@ func CreateSetApprovalForAllCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -3417,7 +3423,7 @@ func CreateTransferFromCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -3622,7 +3628,7 @@ func CreateTransferOwnershipCommand() *cobra.Command { if chainIDErr != nil { return chainIDErr } - safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress + "/propose" + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) fmt.Println("--safe-api not specified, using default (", safeApi, ")") } @@ -3995,13 +4001,7 @@ const ( NativeTokenAddress = "0x0000000000000000000000000000000000000000" ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, txServiceBaseUrl string, deployBytecode []byte, safeOperationType SafeOperationType) error { - // Generate salt - salt, err := GenerateProperSalt(safeAddress) - if err != nil { - return fmt.Errorf("failed to generate salt: %v", err) - } - +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) @@ -4012,25 +4012,10 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, txServiceBaseUrl, SafeOperationType(safeOperationType)) -} - -func GenerateProperSalt(from common.Address) ([32]byte, error) { - var salt [32]byte - - // Copy the 'from' address to the first 20 bytes of the salt - copy(salt[:20], from[:]) - - // Generate random bytes for the remaining 12 bytes - _, err := rand.Read(salt[20:]) - if err != nil { - return [32]byte{}, fmt.Errorf("failed to generate random bytes: %w", err) - } - - return salt, nil + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType)) } -func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, txServiceBaseUrl string, safeOperationType SafeOperationType) error { +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -4094,7 +4079,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress "safeTxHash": safeTxHash.Hex(), "sender": key.Address.Hex(), "signature": senderSignature, - "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", txServiceBaseUrl), + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", safeApi), } // Marshal the request body to JSON @@ -4104,7 +4089,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress } // Send the request to the Safe Transaction Service - req, err := http.NewRequest("POST", txServiceBaseUrl, bytes.NewBuffer(jsonBody)) + req, err := http.NewRequest("POST", safeApi, bytes.NewBuffer(jsonBody)) if err != nil { return fmt.Errorf("failed to create request: %v", err) } From 69de02b07d5d69c479f0b83735ab08d994a198de Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 19:56:57 -0300 Subject: [PATCH 17/22] fix: imports --- evm/generators.go | 6 ++++-- examples/ownable-erc-721/OwnableERC721.go | 11 ++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index 3adf631..9c86502 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -799,6 +799,8 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"golang.org/x/term"`}}, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/moonstream-to/seer/bindings/GnosisSafe"`}}, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/moonstream-to/seer/bindings/CreateCall"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/common/math"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/crypto"`}}, ) } return true @@ -1117,7 +1119,7 @@ const ( ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt []byte) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) @@ -1288,7 +1290,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var timeout uint var safeAddress, safeApi, safeCreateCall, safeSaltRaw string var safeOperationType uint8 - var safeSalt [32]byte + var safeSalt []byte {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 5f995e1..7bd36c0 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -22,8 +22,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/signer/core/apitypes" - "github.com/quan8/go-ethereum/common/math" - "github.com/quan8/go-ethereum/crypto" // Reference imports to suppress errors if they are not otherwise used. "encoding/hex" @@ -38,6 +36,10 @@ import ( "github.com/moonstream-to/seer/bindings/GnosisSafe" "github.com/spf13/cobra" "golang.org/x/term" + + // OwnableERC721MetaData contains all meta data concerning the OwnableERC721 contract. + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" ) var ( @@ -52,7 +54,6 @@ var ( _ = abi.ConvertType ) -// OwnableERC721MetaData contains all meta data concerning the OwnableERC721 contract. var OwnableERC721MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x60806040523480156200001157600080fd5b50604051620019fe380380620019fe833981016040819052620000349162000332565b8251839083906200004d906000906020850190620001bf565b50805162000063906001906020840190620001bf565b505050620000806200007a6200009460201b60201c565b62000098565b6200008b81620000ea565b505050620003fc565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6006546001600160a01b031633146200014a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6001600160a01b038116620001b15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000141565b620001bc8162000098565b50565b828054620001cd90620003bf565b90600052602060002090601f016020900481019282620001f157600085556200023c565b82601f106200020c57805160ff19168380011785556200023c565b828001600101855582156200023c579182015b828111156200023c5782518255916020019190600101906200021f565b506200024a9291506200024e565b5090565b5b808211156200024a57600081556001016200024f565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200028d57600080fd5b81516001600160401b0380821115620002aa57620002aa62000265565b604051601f8301601f19908116603f01168101908282118183101715620002d557620002d562000265565b81604052838152602092508683858801011115620002f257600080fd5b600091505b83821015620003165785820183015181830184015290820190620002f7565b83821115620003285760008385830101525b9695505050505050565b6000806000606084860312156200034857600080fd5b83516001600160401b03808211156200036057600080fd5b6200036e878388016200027b565b945060208601519150808211156200038557600080fd5b5062000394868287016200027b565b604086015190935090506001600160a01b0381168114620003b457600080fd5b809150509250925092565b600181811c90821680620003d457607f821691505b60208210811415620003f657634e487b7160e01b600052602260045260246000fd5b50919050565b6115f2806200040c6000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a22cb46511610071578063a22cb4651461021b578063b88d4fde1461022e578063c87b56dd14610241578063e985e9c514610254578063f2fde38b1461029057600080fd5b806370a08231146101d9578063715018a6146101fa5780638da5cb5b1461020257806395d89b411461021357600080fd5b806323b872dd116100de57806323b872dd1461018d57806340c10f19146101a057806342842e0e146101b35780636352211e146101c657600080fd5b806301ffc9a71461011057806306fdde0314610138578063081812fc1461014d578063095ea7b314610178575b600080fd5b61012361011e3660046110cd565b6102a3565b60405190151581526020015b60405180910390f35b6101406102f5565b60405161012f9190611142565b61016061015b366004611155565b610387565b6040516001600160a01b03909116815260200161012f565b61018b61018636600461118a565b610421565b005b61018b61019b3660046111b4565b610537565b61018b6101ae36600461118a565b610568565b61018b6101c13660046111b4565b6105a0565b6101606101d4366004611155565b6105bb565b6101ec6101e73660046111f0565b610632565b60405190815260200161012f565b61018b6106b9565b6006546001600160a01b0316610160565b6101406106ef565b61018b61022936600461120b565b6106fe565b61018b61023c36600461125d565b610709565b61014061024f366004611155565b610741565b610123610262366004611339565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61018b61029e3660046111f0565b610829565b60006001600160e01b031982166380ac58cd60e01b14806102d457506001600160e01b03198216635b5e139f60e01b145b806102ef57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546103049061136c565b80601f01602080910402602001604051908101604052809291908181526020018280546103309061136c565b801561037d5780601f106103525761010080835404028352916020019161037d565b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166104055760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061042c826105bb565b9050806001600160a01b0316836001600160a01b0316141561049a5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016103fc565b336001600160a01b03821614806104b657506104b68133610262565b6105285760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016103fc565b61053283836108c4565b505050565b6105413382610932565b61055d5760405162461bcd60e51b81526004016103fc906113a7565b610532838383610a29565b6006546001600160a01b031633146105925760405162461bcd60e51b81526004016103fc906113f8565b61059c8282610bc9565b5050565b61053283838360405180602001604052806000815250610709565b6000818152600260205260408120546001600160a01b0316806102ef5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016103fc565b60006001600160a01b03821661069d5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016103fc565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b031633146106e35760405162461bcd60e51b81526004016103fc906113f8565b6106ed6000610be3565b565b6060600180546103049061136c565b61059c338383610c35565b6107133383610932565b61072f5760405162461bcd60e51b81526004016103fc906113a7565b61073b84848484610d04565b50505050565b6000818152600260205260409020546060906001600160a01b03166107c05760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016103fc565b60006107d760408051602081019091526000815290565b905060008151116107f75760405180602001604052806000815250610822565b8061080184610d37565b60405160200161081292919061142d565b6040516020818303038152906040525b9392505050565b6006546001600160a01b031633146108535760405162461bcd60e51b81526004016103fc906113f8565b6001600160a01b0381166108b85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103fc565b6108c181610be3565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906108f9826105bb565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166109ab5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016103fc565b60006109b6836105bb565b9050806001600160a01b0316846001600160a01b031614806109f15750836001600160a01b03166109e684610387565b6001600160a01b0316145b80610a2157506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316610a3c826105bb565b6001600160a01b031614610aa45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016103fc565b6001600160a01b038216610b065760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103fc565b610b116000826108c4565b6001600160a01b0383166000908152600360205260408120805460019290610b3a908490611472565b90915550506001600160a01b0382166000908152600360205260408120805460019290610b68908490611489565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61059c828260405180602001604052806000815250610e35565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b03161415610c975760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610d0f848484610a29565b610d1b84848484610e68565b61073b5760405162461bcd60e51b81526004016103fc906114a1565b606081610d5b5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610d855780610d6f816114f3565b9150610d7e9050600a83611524565b9150610d5f565b60008167ffffffffffffffff811115610da057610da0611247565b6040519080825280601f01601f191660200182016040528015610dca576020820181803683370190505b5090505b8415610a2157610ddf600183611472565b9150610dec600a86611538565b610df7906030611489565b60f81b818381518110610e0c57610e0c61154c565b60200101906001600160f81b031916908160001a905350610e2e600a86611524565b9450610dce565b610e3f8383610f75565b610e4c6000848484610e68565b6105325760405162461bcd60e51b81526004016103fc906114a1565b60006001600160a01b0384163b15610f6a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610eac903390899088908890600401611562565b602060405180830381600087803b158015610ec657600080fd5b505af1925050508015610ef6575060408051601f3d908101601f19168201909252610ef39181019061159f565b60015b610f50573d808015610f24576040519150601f19603f3d011682016040523d82523d6000602084013e610f29565b606091505b508051610f485760405162461bcd60e51b81526004016103fc906114a1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610a21565b506001949350505050565b6001600160a01b038216610fcb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103fc565b6000818152600260205260409020546001600160a01b0316156110305760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103fc565b6001600160a01b0382166000908152600360205260408120805460019290611059908490611489565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b0319811681146108c157600080fd5b6000602082840312156110df57600080fd5b8135610822816110b7565b60005b838110156111055781810151838201526020016110ed565b8381111561073b5750506000910152565b6000815180845261112e8160208601602086016110ea565b601f01601f19169290920160200192915050565b6020815260006108226020830184611116565b60006020828403121561116757600080fd5b5035919050565b80356001600160a01b038116811461118557600080fd5b919050565b6000806040838503121561119d57600080fd5b6111a68361116e565b946020939093013593505050565b6000806000606084860312156111c957600080fd5b6111d28461116e565b92506111e06020850161116e565b9150604084013590509250925092565b60006020828403121561120257600080fd5b6108228261116e565b6000806040838503121561121e57600080fd5b6112278361116e565b91506020830135801515811461123c57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561127357600080fd5b61127c8561116e565b935061128a6020860161116e565b925060408501359150606085013567ffffffffffffffff808211156112ae57600080fd5b818701915087601f8301126112c257600080fd5b8135818111156112d4576112d4611247565b604051601f8201601f19908116603f011681019083821181831017156112fc576112fc611247565b816040528281528a602084870101111561131557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561134c57600080fd5b6113558361116e565b91506113636020840161116e565b90509250929050565b600181811c9082168061138057607f821691505b602082108114156113a157634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000835161143f8184602088016110ea565b8351908301906114538183602088016110ea565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156114845761148461145c565b500390565b6000821982111561149c5761149c61145c565b500190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60006000198214156115075761150761145c565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826115335761153361150e565b500490565b6000826115475761154761150e565b500690565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061159590830184611116565b9695505050505050565b6000602082840312156115b157600080fd5b8151610822816110b756fea264697066735822122061bd7069fbe4cf9497a08868a69ed81fec10d620962d72d34b6772153fc0186364736f6c63430008090033", @@ -1310,7 +1311,7 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var timeout uint var safeAddress, safeApi, safeCreateCall, safeSaltRaw string var safeOperationType uint8 - var safeSalt [32]byte + var safeSalt []byte var name_0 string @@ -4001,7 +4002,7 @@ const ( NativeTokenAddress = "0x0000000000000000000000000000000000000000" ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt []byte) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) From 05dafdb3e8cc5cc64a9a669dc34ce207975f710b Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 21:22:03 -0300 Subject: [PATCH 18/22] Fix: encode call --- evm/generators.go | 32 ++++---- examples/ownable-erc-721/OwnableERC721.go | 96 ++++++++--------------- 2 files changed, 46 insertions(+), 82 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index 9c86502..8e78994 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1119,7 +1119,7 @@ const ( ) -func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt []byte) error { +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) @@ -1290,7 +1290,6 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var timeout uint var safeAddress, safeApi, safeCreateCall, safeSaltRaw string var safeOperationType uint8 - var safeSalt []byte {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1343,7 +1342,6 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if safeSaltRaw == "" { return fmt.Errorf("--safe-salt not specified") } - safeSalt = common.Hex2Bytes(safeSaltRaw) } {{range .DeployHandler.MethodArgs}} @@ -1393,7 +1391,9 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), safeSalt) + var salt [32]byte + copy(salt[:], safeSaltRaw) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), salt) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1687,26 +1687,22 @@ func {{.HandlerName}}() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := {{$structName}}MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("{{ToLowerCamel .MethodName}}", - {{range .MethodArgs}} - {{.CLIVar}}, - {{- end}} - ) - if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) - } + transaction, err := session.{{.MethodName}}( + {{range .MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return err + } + // Create Safe proposal for transaction value := transactionOpts.Value if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 7bd36c0..6e0151f 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -2287,18 +2287,14 @@ func CreateApproveCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("approve", + transaction, err := session.Approve( to0, tokenId, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -2306,7 +2302,7 @@ func CreateApproveCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2484,18 +2480,14 @@ func CreateMintCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("mint", + transaction, err := session.Mint( to0, tokenId, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -2503,7 +2495,7 @@ func CreateMintCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2663,14 +2655,10 @@ func CreateRenounceOwnershipCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("renounceOwnership") + transaction, err := session.RenounceOwnership() + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -2678,7 +2666,7 @@ func CreateRenounceOwnershipCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2858,19 +2846,15 @@ func CreateSafeTransferFromCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("safeTransferFrom", + transaction, err := session.SafeTransferFrom( from0, to0, tokenId, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -2878,7 +2862,7 @@ func CreateSafeTransferFromCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3079,20 +3063,16 @@ func CreateSafeTransferFrom0Command() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("safeTransferFrom0", + transaction, err := session.SafeTransferFrom0( from0, to0, tokenId, data, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -3100,7 +3080,7 @@ func CreateSafeTransferFrom0Command() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3286,18 +3266,14 @@ func CreateSetApprovalForAllCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("setApprovalForAll", + transaction, err := session.SetApprovalForAll( operator, approved, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -3305,7 +3281,7 @@ func CreateSetApprovalForAllCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3492,19 +3468,15 @@ func CreateTransferFromCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("transferFrom", + transaction, err := session.TransferFrom( from0, to0, tokenId, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -3512,7 +3484,7 @@ func CreateTransferFromCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3684,17 +3656,13 @@ func CreateTransferOwnershipCommand() *cobra.Command { if safeAddress != "" { // Generate transaction data - abi, err := OwnableERC721MetaData.GetAbi() - if err != nil { - return fmt.Errorf("failed to get ABI: %v", err) - } - // TODO: this is a workaround to match the original method name in the ABI, need to fix to work with every method name - packedData, err := abi.Pack("transferOwnership", + transaction, err := session.TransferOwnership( newOwner, ) + if err != nil { - return fmt.Errorf("failed to pack transaction data: %v", err) + return err } // Create Safe proposal for transaction @@ -3702,7 +3670,7 @@ func CreateTransferOwnershipCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, packedData, value, safeApi, SafeOperationType(safeOperationType)) + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } From 5007b25c163666b707c6dc7fe7b863985bb50c51 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 21:27:42 -0300 Subject: [PATCH 19/22] Feat: prompt random salt to be accepted by the user --- evm/generators.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/evm/generators.go b/evm/generators.go index 8e78994..199ea9c 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1290,6 +1290,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var timeout uint var safeAddress, safeApi, safeCreateCall, safeSaltRaw string var safeOperationType uint8 + var salt [32]byte {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1340,7 +1341,21 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { } if safeSaltRaw == "" { - return fmt.Errorf("--safe-salt not specified") + fmt.Println("--safe-salt not specified, generating random salt") + _, err := rand.Read(salt[:]) + if err != nil { + return fmt.Errorf("failed to generate random salt: %v", err) + } + // prompt user to accept random salt + fmt.Println("Generated salt:", common.Bytes2Hex(salt[:])) + fmt.Println("Please check the salt and confirm (y/n)") + var confirm string + fmt.Scanln(&confirm) + if confirm != "y" { + return fmt.Errorf("salt not accepted, please specify a valid salt") + } + } else { + copy(salt[:], safeSaltRaw) } } @@ -1391,8 +1406,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - var salt [32]byte - copy(salt[:], safeSaltRaw) + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), salt) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) From 261cb31a445e297e33963b1f1c773864272350e6 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Mon, 30 Sep 2024 21:29:32 -0300 Subject: [PATCH 20/22] go mod tidy --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 4b6f090..5adb2c5 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,9 @@ require ( github.com/iancoleman/strcase v0.3.0 github.com/jackc/pgx/v5 v5.5.3 github.com/spf13/cobra v1.8.0 - golang.org/x/crypto v0.20.0 - golang.org/x/term v0.17.0 - golang.org/x/tools v0.15.0 + golang.org/x/crypto v0.23.0 + golang.org/x/term v0.20.0 + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d google.golang.org/api v0.167.0 google.golang.org/protobuf v1.34.2 ) @@ -66,8 +66,8 @@ require ( go.opentelemetry.io/otel/metric v1.23.0 // indirect go.opentelemetry.io/otel/trace v1.23.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect diff --git a/go.sum b/go.sum index 1eb541b..e51d5aa 100644 --- a/go.sum +++ b/go.sum @@ -273,8 +273,8 @@ go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5Ukgg golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= @@ -282,8 +282,8 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -293,8 +293,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= @@ -321,8 +321,8 @@ golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -338,8 +338,8 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= From db738c97675c977129f4df077d2918982d89a717 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Tue, 1 Oct 2024 08:50:04 -0300 Subject: [PATCH 21/22] Update README --- README.md | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3134793..0d32ac9 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ This will create an executable file called `ownable-erc-721` (on Windows, you ma Try running it: -``` +```bash $ ./ownable-erc-721 -h Interact with the OwnableERC721 contract @@ -120,12 +120,6 @@ Commands which submit transactions transfer-from Execute the TransferFrom method on a OwnableERC721 contract transfer-ownership Execute the TransferOwnership method on a OwnableERC721 contract -Commands which propose transactions to Safe - safe Safe address to propose transactions to - safe-api Override default Safe API URL (default "https://safe-client.safe.global/v1/chains/${CHAIN_ID}/transactions/${SAFE_ADDRESS}/propose") - safe-operation Type of operation to propose: 0 (Call) or 1 (DelegateCall) (default 0 for deployment and 1 for function calls) - safe-create-call Address of the contract to deploy if the operation is a deployment (default "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4") - Additional Commands: completion Generate the autocompletion script for the specified shell help Help about any command @@ -136,6 +130,34 @@ Flags: Use "ownable-erc-721 [command] --help" for more information about a command. ``` +```bash +$ ./ownable-erc-721 approve -h +Execute the Approve method on a OwnableERC721 contract + +Usage: + ownable-erc-721 approve [flags] + +Flags: + --contract string Address of the contract to interact with + --gas-limit uint Gas limit for the transaction + --gas-price string Gas price to use for the transaction + -h, --help help for approve + --keyfile string Path to the keystore file to use for the transaction + --max-fee-per-gas string Maximum fee per gas to use for the (EIP-1559) transaction + --max-priority-fee-per-gas string Maximum priority fee per gas to use for the (EIP-1559) transaction + --nonce string Nonce to use for the transaction + --password string Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes) + --rpc string URL of the JSONRPC API to use + --safe string Address of the Safe contract + --safe-api string Safe API for the Safe Transaction Service (optional) + --safe-operation uint8 Safe operation type: 0 (Call) or 1 (DelegateCall) + --simulate Simulate the transaction without sending it + --timeout uint Timeout (in seconds) for interactions with the JSONRPC API (default 60) + --to-0 string to-0 argument (common.Address) + --token-id string token-id argument + --value string Value to send with the transaction +``` + # Crawler That part of seer responsible for crawling raw blocks,tx_calls and events from the blockchain. From 53b12cb4718ebbf4a93cb2871b816bd3439b7d20 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Tue, 1 Oct 2024 08:56:13 -0300 Subject: [PATCH 22/22] Update Salt Prompt --- evm/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/generators.go b/evm/generators.go index 199ea9c..6759baa 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -1351,7 +1351,7 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { fmt.Println("Please check the salt and confirm (y/n)") var confirm string fmt.Scanln(&confirm) - if confirm != "y" { + if confirm != "y" && confirm != "Y" && confirm != "\n" && confirm != "" { return fmt.Errorf("salt not accepted, please specify a valid salt") } } else {