├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── contracts_erc20 └── erc20.go ├── go.mod ├── go.sum └── main.go /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # If you prefer the allow list template instead of the deny list, see community template: 2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 3 | # 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | 11 | # Test binary, built with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Dependency directories (remove the comment below to include it) 18 | # vendor/ 19 | 20 | # Go workspace file 21 | go.work 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 deltartificial 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 🥪 MEV Snipping Copytrader Go 3 | 4 | Snipe new tokens bought by the most powerful MEV bots (Sandwitch, Arbitrage, Snipping) in Go on EVM networks. 5 | 6 | This bot scans contracts such as MEV bots (Sandwitch, Arbitrage, Snipping) and searches for new ERC-20 tokens purchased, this bot allows you to take advantage of the powerful checks of MEV bots (Poison tokens, Salmonella tokens etc) to discover safer tokens. 7 | 8 | ### Config 9 | - WssRpcNode (string) - Url of your WSS RPC Node. 10 | - SandwichBotEOAAddress (string) - Address of MEV Bot caller. 11 | - SandwitchBotContractAddress (string) - Address of MEV Contract. 12 | 13 | ### Install 14 | Requirements : Go. 15 | - `go get` 16 | - `go run .` 17 | 18 | ### Twitter 19 | @deltartificial 20 | -------------------------------------------------------------------------------- /contracts_erc20/erc20.go: -------------------------------------------------------------------------------- 1 | // Code generated - DO NOT EDIT. 2 | // This file is a generated binding and any manual changes will be lost. 3 | 4 | package token 5 | 6 | import ( 7 | "errors" 8 | "math/big" 9 | "strings" 10 | 11 | ethereum "github.com/ethereum/go-ethereum" 12 | "github.com/ethereum/go-ethereum/accounts/abi" 13 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 14 | "github.com/ethereum/go-ethereum/common" 15 | "github.com/ethereum/go-ethereum/core/types" 16 | "github.com/ethereum/go-ethereum/event" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var ( 21 | _ = errors.New 22 | _ = big.NewInt 23 | _ = strings.NewReader 24 | _ = ethereum.NotFound 25 | _ = bind.Bind 26 | _ = common.Big1 27 | _ = types.BloomLookup 28 | _ = event.NewSubscription 29 | _ = abi.ConvertType 30 | ) 31 | 32 | // TokenMetaData contains all meta data concerning the Token contract. 33 | var TokenMetaData = &bind.MetaData{ 34 | ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", 35 | Bin: "0x608060405234801562000010575f80fd5b5060405162001756380380620017568339818101604052810190620000369190620001e7565b8160039081620000479190620004a1565b508060049081620000599190620004a1565b50505062000585565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000c3826200007b565b810181811067ffffffffffffffff82111715620000e557620000e46200008b565b5b80604052505050565b5f620000f962000062565b9050620001078282620000b8565b919050565b5f67ffffffffffffffff8211156200012957620001286200008b565b5b62000134826200007b565b9050602081019050919050565b5f5b838110156200016057808201518184015260208101905062000143565b5f8484015250505050565b5f620001816200017b846200010c565b620000ee565b905082815260208101848484011115620001a0576200019f62000077565b5b620001ad84828562000141565b509392505050565b5f82601f830112620001cc57620001cb62000073565b5b8151620001de8482602086016200016b565b91505092915050565b5f80604083850312156200020057620001ff6200006b565b5b5f83015167ffffffffffffffff81111562000220576200021f6200006f565b5b6200022e85828601620001b5565b925050602083015167ffffffffffffffff8111156200025257620002516200006f565b5b6200026085828601620001b5565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002b957607f821691505b602082108103620002cf57620002ce62000274565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003337fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002f6565b6200033f8683620002f6565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000389620003836200037d8462000357565b62000360565b62000357565b9050919050565b5f819050919050565b620003a48362000369565b620003bc620003b38262000390565b84845462000302565b825550505050565b5f90565b620003d2620003c4565b620003df81848462000399565b505050565b5b818110156200040657620003fa5f82620003c8565b600181019050620003e5565b5050565b601f82111562000455576200041f81620002d5565b6200042a84620002e7565b810160208510156200043a578190505b620004526200044985620002e7565b830182620003e4565b50505b505050565b5f82821c905092915050565b5f620004775f19846008026200045a565b1980831691505092915050565b5f62000491838362000466565b9150826002028217905092915050565b620004ac826200026a565b67ffffffffffffffff811115620004c857620004c76200008b565b5b620004d48254620002a1565b620004e18282856200040a565b5f60209050601f83116001811462000517575f841562000502578287015190505b6200050e858262000484565b8655506200057d565b601f1984166200052786620002d5565b5f5b82811015620005505784890151825560018201915060208501945060208101905062000529565b868310156200057057848901516200056c601f89168262000466565b8355505b6001600288020188555050505b505050505050565b6111c380620005935f395ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c8063395093511161006f578063395093511461016557806370a082311461019557806395d89b41146101c5578063a457c2d7146101e3578063a9059cbb14610213578063dd62ed3e14610243576100a7565b806306fdde03146100ab578063095ea7b3146100c957806318160ddd146100f957806323b872dd14610117578063313ce56714610147575b5f80fd5b6100b3610273565b6040516100c09190610add565b60405180910390f35b6100e360048036038101906100de9190610b8e565b610303565b6040516100f09190610be6565b60405180910390f35b610101610325565b60405161010e9190610c0e565b60405180910390f35b610131600480360381019061012c9190610c27565b61032e565b60405161013e9190610be6565b60405180910390f35b61014f61035c565b60405161015c9190610c92565b60405180910390f35b61017f600480360381019061017a9190610b8e565b610364565b60405161018c9190610be6565b60405180910390f35b6101af60048036038101906101aa9190610cab565b61039a565b6040516101bc9190610c0e565b60405180910390f35b6101cd6103df565b6040516101da9190610add565b60405180910390f35b6101fd60048036038101906101f89190610b8e565b61046f565b60405161020a9190610be6565b60405180910390f35b61022d60048036038101906102289190610b8e565b6104e4565b60405161023a9190610be6565b60405180910390f35b61025d60048036038101906102589190610cd6565b610506565b60405161026a9190610c0e565b60405180910390f35b60606003805461028290610d41565b80601f01602080910402602001604051908101604052809291908181526020018280546102ae90610d41565b80156102f95780601f106102d0576101008083540402835291602001916102f9565b820191905f5260205f20905b8154815290600101906020018083116102dc57829003601f168201915b5050505050905090565b5f8061030d610588565b905061031a81858561058f565b600191505092915050565b5f600254905090565b5f80610338610588565b9050610345858285610752565b6103508585856107dd565b60019150509392505050565b5f6012905090565b5f8061036e610588565b905061038f8185856103808589610506565b61038a9190610d9e565b61058f565b600191505092915050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6060600480546103ee90610d41565b80601f016020809104026020016040519081016040528092919081815260200182805461041a90610d41565b80156104655780601f1061043c57610100808354040283529160200191610465565b820191905f5260205f20905b81548152906001019060200180831161044857829003601f168201915b5050505050905090565b5f80610479610588565b90505f6104868286610506565b9050838110156104cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c290610e41565b60405180910390fd5b6104d8828686840361058f565b60019250505092915050565b5f806104ee610588565b90506104fb8185856107dd565b600191505092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f490610ecf565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361066b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066290610f5d565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516107459190610c0e565b60405180910390a3505050565b5f61075d8484610506565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146107d757818110156107c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c090610fc5565b60405180910390fd5b6107d6848484840361058f565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361084b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084290611053565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036108b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b0906110e1565b60405180910390fd5b6108c4838383610a49565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093e9061116f565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610a309190610c0e565b60405180910390a3610a43848484610a4e565b50505050565b505050565b505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015610a8a578082015181840152602081019050610a6f565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610aaf82610a53565b610ab98185610a5d565b9350610ac9818560208601610a6d565b610ad281610a95565b840191505092915050565b5f6020820190508181035f830152610af58184610aa5565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610b2a82610b01565b9050919050565b610b3a81610b20565b8114610b44575f80fd5b50565b5f81359050610b5581610b31565b92915050565b5f819050919050565b610b6d81610b5b565b8114610b77575f80fd5b50565b5f81359050610b8881610b64565b92915050565b5f8060408385031215610ba457610ba3610afd565b5b5f610bb185828601610b47565b9250506020610bc285828601610b7a565b9150509250929050565b5f8115159050919050565b610be081610bcc565b82525050565b5f602082019050610bf95f830184610bd7565b92915050565b610c0881610b5b565b82525050565b5f602082019050610c215f830184610bff565b92915050565b5f805f60608486031215610c3e57610c3d610afd565b5b5f610c4b86828701610b47565b9350506020610c5c86828701610b47565b9250506040610c6d86828701610b7a565b9150509250925092565b5f60ff82169050919050565b610c8c81610c77565b82525050565b5f602082019050610ca55f830184610c83565b92915050565b5f60208284031215610cc057610cbf610afd565b5b5f610ccd84828501610b47565b91505092915050565b5f8060408385031215610cec57610ceb610afd565b5b5f610cf985828601610b47565b9250506020610d0a85828601610b47565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610d5857607f821691505b602082108103610d6b57610d6a610d14565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610da882610b5b565b9150610db383610b5b565b9250828201905080821115610dcb57610dca610d71565b5b92915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f775f8201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b5f610e2b602583610a5d565b9150610e3682610dd1565b604082019050919050565b5f6020820190508181035f830152610e5881610e1f565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f610eb9602483610a5d565b9150610ec482610e5f565b604082019050919050565b5f6020820190508181035f830152610ee681610ead565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f610f47602283610a5d565b9150610f5282610eed565b604082019050919050565b5f6020820190508181035f830152610f7481610f3b565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000005f82015250565b5f610faf601d83610a5d565b9150610fba82610f7b565b602082019050919050565b5f6020820190508181035f830152610fdc81610fa3565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f61103d602583610a5d565b915061104882610fe3565b604082019050919050565b5f6020820190508181035f83015261106a81611031565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f6110cb602383610a5d565b91506110d682611071565b604082019050919050565b5f6020820190508181035f8301526110f8816110bf565b9050919050565b7f45524332303a207472616e7366657220616d6f756e74206578636565647320625f8201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b5f611159602683610a5d565b9150611164826110ff565b604082019050919050565b5f6020820190508181035f8301526111868161114d565b905091905056fea26469706673582212208ad260c60fb69476f16f34c7a749f6abc3cf0b7ab4561d7c0c6ffd2c10a4fe5764736f6c63430008140033", 36 | } 37 | 38 | // TokenABI is the input ABI used to generate the binding from. 39 | // Deprecated: Use TokenMetaData.ABI instead. 40 | var TokenABI = TokenMetaData.ABI 41 | 42 | // TokenBin is the compiled bytecode used for deploying new contracts. 43 | // Deprecated: Use TokenMetaData.Bin instead. 44 | var TokenBin = TokenMetaData.Bin 45 | 46 | // DeployToken deploys a new Ethereum contract, binding an instance of Token to it. 47 | func DeployToken(auth *bind.TransactOpts, backend bind.ContractBackend, name_ string, symbol_ string) (common.Address, *types.Transaction, *Token, error) { 48 | parsed, err := TokenMetaData.GetAbi() 49 | if err != nil { 50 | return common.Address{}, nil, nil, err 51 | } 52 | if parsed == nil { 53 | return common.Address{}, nil, nil, errors.New("GetABI returned nil") 54 | } 55 | 56 | address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TokenBin), backend, name_, symbol_) 57 | if err != nil { 58 | return common.Address{}, nil, nil, err 59 | } 60 | return address, tx, &Token{TokenCaller: TokenCaller{contract: contract}, TokenTransactor: TokenTransactor{contract: contract}, TokenFilterer: TokenFilterer{contract: contract}}, nil 61 | } 62 | 63 | // Token is an auto generated Go binding around an Ethereum contract. 64 | type Token struct { 65 | TokenCaller // Read-only binding to the contract 66 | TokenTransactor // Write-only binding to the contract 67 | TokenFilterer // Log filterer for contract events 68 | } 69 | 70 | // TokenCaller is an auto generated read-only Go binding around an Ethereum contract. 71 | type TokenCaller struct { 72 | contract *bind.BoundContract // Generic contract wrapper for the low level calls 73 | } 74 | 75 | // TokenTransactor is an auto generated write-only Go binding around an Ethereum contract. 76 | type TokenTransactor struct { 77 | contract *bind.BoundContract // Generic contract wrapper for the low level calls 78 | } 79 | 80 | // TokenFilterer is an auto generated log filtering Go binding around an Ethereum contract events. 81 | type TokenFilterer struct { 82 | contract *bind.BoundContract // Generic contract wrapper for the low level calls 83 | } 84 | 85 | // TokenSession is an auto generated Go binding around an Ethereum contract, 86 | // with pre-set call and transact options. 87 | type TokenSession struct { 88 | Contract *Token // Generic contract binding to set the session for 89 | CallOpts bind.CallOpts // Call options to use throughout this session 90 | TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session 91 | } 92 | 93 | // TokenCallerSession is an auto generated read-only Go binding around an Ethereum contract, 94 | // with pre-set call options. 95 | type TokenCallerSession struct { 96 | Contract *TokenCaller // Generic contract caller binding to set the session for 97 | CallOpts bind.CallOpts // Call options to use throughout this session 98 | } 99 | 100 | // TokenTransactorSession is an auto generated write-only Go binding around an Ethereum contract, 101 | // with pre-set transact options. 102 | type TokenTransactorSession struct { 103 | Contract *TokenTransactor // Generic contract transactor binding to set the session for 104 | TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session 105 | } 106 | 107 | // TokenRaw is an auto generated low-level Go binding around an Ethereum contract. 108 | type TokenRaw struct { 109 | Contract *Token // Generic contract binding to access the raw methods on 110 | } 111 | 112 | // TokenCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. 113 | type TokenCallerRaw struct { 114 | Contract *TokenCaller // Generic read-only contract binding to access the raw methods on 115 | } 116 | 117 | // TokenTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. 118 | type TokenTransactorRaw struct { 119 | Contract *TokenTransactor // Generic write-only contract binding to access the raw methods on 120 | } 121 | 122 | // NewToken creates a new instance of Token, bound to a specific deployed contract. 123 | func NewToken(address common.Address, backend bind.ContractBackend) (*Token, error) { 124 | contract, err := bindToken(address, backend, backend, backend) 125 | if err != nil { 126 | return nil, err 127 | } 128 | return &Token{TokenCaller: TokenCaller{contract: contract}, TokenTransactor: TokenTransactor{contract: contract}, TokenFilterer: TokenFilterer{contract: contract}}, nil 129 | } 130 | 131 | // NewTokenCaller creates a new read-only instance of Token, bound to a specific deployed contract. 132 | func NewTokenCaller(address common.Address, caller bind.ContractCaller) (*TokenCaller, error) { 133 | contract, err := bindToken(address, caller, nil, nil) 134 | if err != nil { 135 | return nil, err 136 | } 137 | return &TokenCaller{contract: contract}, nil 138 | } 139 | 140 | // NewTokenTransactor creates a new write-only instance of Token, bound to a specific deployed contract. 141 | func NewTokenTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenTransactor, error) { 142 | contract, err := bindToken(address, nil, transactor, nil) 143 | if err != nil { 144 | return nil, err 145 | } 146 | return &TokenTransactor{contract: contract}, nil 147 | } 148 | 149 | // NewTokenFilterer creates a new log filterer instance of Token, bound to a specific deployed contract. 150 | func NewTokenFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenFilterer, error) { 151 | contract, err := bindToken(address, nil, nil, filterer) 152 | if err != nil { 153 | return nil, err 154 | } 155 | return &TokenFilterer{contract: contract}, nil 156 | } 157 | 158 | // bindToken binds a generic wrapper to an already deployed contract. 159 | func bindToken(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { 160 | parsed, err := TokenMetaData.GetAbi() 161 | if err != nil { 162 | return nil, err 163 | } 164 | return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil 165 | } 166 | 167 | // Call invokes the (constant) contract method with params as input values and 168 | // sets the output to result. The result type might be a single field for simple 169 | // returns, a slice of interfaces for anonymous returns and a struct for named 170 | // returns. 171 | func (_Token *TokenRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { 172 | return _Token.Contract.TokenCaller.contract.Call(opts, result, method, params...) 173 | } 174 | 175 | // Transfer initiates a plain transaction to move funds to the contract, calling 176 | // its default method if one is available. 177 | func (_Token *TokenRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { 178 | return _Token.Contract.TokenTransactor.contract.Transfer(opts) 179 | } 180 | 181 | // Transact invokes the (paid) contract method with params as input values. 182 | func (_Token *TokenRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { 183 | return _Token.Contract.TokenTransactor.contract.Transact(opts, method, params...) 184 | } 185 | 186 | // Call invokes the (constant) contract method with params as input values and 187 | // sets the output to result. The result type might be a single field for simple 188 | // returns, a slice of interfaces for anonymous returns and a struct for named 189 | // returns. 190 | func (_Token *TokenCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { 191 | return _Token.Contract.contract.Call(opts, result, method, params...) 192 | } 193 | 194 | // Transfer initiates a plain transaction to move funds to the contract, calling 195 | // its default method if one is available. 196 | func (_Token *TokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { 197 | return _Token.Contract.contract.Transfer(opts) 198 | } 199 | 200 | // Transact invokes the (paid) contract method with params as input values. 201 | func (_Token *TokenTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { 202 | return _Token.Contract.contract.Transact(opts, method, params...) 203 | } 204 | 205 | // Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. 206 | // 207 | // Solidity: function allowance(address owner, address spender) view returns(uint256) 208 | func (_Token *TokenCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { 209 | var out []interface{} 210 | err := _Token.contract.Call(opts, &out, "allowance", owner, spender) 211 | 212 | if err != nil { 213 | return *new(*big.Int), err 214 | } 215 | 216 | out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) 217 | 218 | return out0, err 219 | 220 | } 221 | 222 | // Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. 223 | // 224 | // Solidity: function allowance(address owner, address spender) view returns(uint256) 225 | func (_Token *TokenSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { 226 | return _Token.Contract.Allowance(&_Token.CallOpts, owner, spender) 227 | } 228 | 229 | // Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. 230 | // 231 | // Solidity: function allowance(address owner, address spender) view returns(uint256) 232 | func (_Token *TokenCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { 233 | return _Token.Contract.Allowance(&_Token.CallOpts, owner, spender) 234 | } 235 | 236 | // BalanceOf is a free data retrieval call binding the contract method 0x70a08231. 237 | // 238 | // Solidity: function balanceOf(address account) view returns(uint256) 239 | func (_Token *TokenCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { 240 | var out []interface{} 241 | err := _Token.contract.Call(opts, &out, "balanceOf", account) 242 | 243 | if err != nil { 244 | return *new(*big.Int), err 245 | } 246 | 247 | out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) 248 | 249 | return out0, err 250 | 251 | } 252 | 253 | // BalanceOf is a free data retrieval call binding the contract method 0x70a08231. 254 | // 255 | // Solidity: function balanceOf(address account) view returns(uint256) 256 | func (_Token *TokenSession) BalanceOf(account common.Address) (*big.Int, error) { 257 | return _Token.Contract.BalanceOf(&_Token.CallOpts, account) 258 | } 259 | 260 | // BalanceOf is a free data retrieval call binding the contract method 0x70a08231. 261 | // 262 | // Solidity: function balanceOf(address account) view returns(uint256) 263 | func (_Token *TokenCallerSession) BalanceOf(account common.Address) (*big.Int, error) { 264 | return _Token.Contract.BalanceOf(&_Token.CallOpts, account) 265 | } 266 | 267 | // Decimals is a free data retrieval call binding the contract method 0x313ce567. 268 | // 269 | // Solidity: function decimals() view returns(uint8) 270 | func (_Token *TokenCaller) Decimals(opts *bind.CallOpts) (uint8, error) { 271 | var out []interface{} 272 | err := _Token.contract.Call(opts, &out, "decimals") 273 | 274 | if err != nil { 275 | return *new(uint8), err 276 | } 277 | 278 | out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) 279 | 280 | return out0, err 281 | 282 | } 283 | 284 | // Decimals is a free data retrieval call binding the contract method 0x313ce567. 285 | // 286 | // Solidity: function decimals() view returns(uint8) 287 | func (_Token *TokenSession) Decimals() (uint8, error) { 288 | return _Token.Contract.Decimals(&_Token.CallOpts) 289 | } 290 | 291 | // Decimals is a free data retrieval call binding the contract method 0x313ce567. 292 | // 293 | // Solidity: function decimals() view returns(uint8) 294 | func (_Token *TokenCallerSession) Decimals() (uint8, error) { 295 | return _Token.Contract.Decimals(&_Token.CallOpts) 296 | } 297 | 298 | // Name is a free data retrieval call binding the contract method 0x06fdde03. 299 | // 300 | // Solidity: function name() view returns(string) 301 | func (_Token *TokenCaller) Name(opts *bind.CallOpts) (string, error) { 302 | var out []interface{} 303 | err := _Token.contract.Call(opts, &out, "name") 304 | 305 | if err != nil { 306 | return *new(string), err 307 | } 308 | 309 | out0 := *abi.ConvertType(out[0], new(string)).(*string) 310 | 311 | return out0, err 312 | 313 | } 314 | 315 | // Name is a free data retrieval call binding the contract method 0x06fdde03. 316 | // 317 | // Solidity: function name() view returns(string) 318 | func (_Token *TokenSession) Name() (string, error) { 319 | return _Token.Contract.Name(&_Token.CallOpts) 320 | } 321 | 322 | // Name is a free data retrieval call binding the contract method 0x06fdde03. 323 | // 324 | // Solidity: function name() view returns(string) 325 | func (_Token *TokenCallerSession) Name() (string, error) { 326 | return _Token.Contract.Name(&_Token.CallOpts) 327 | } 328 | 329 | // Symbol is a free data retrieval call binding the contract method 0x95d89b41. 330 | // 331 | // Solidity: function symbol() view returns(string) 332 | func (_Token *TokenCaller) Symbol(opts *bind.CallOpts) (string, error) { 333 | var out []interface{} 334 | err := _Token.contract.Call(opts, &out, "symbol") 335 | 336 | if err != nil { 337 | return *new(string), err 338 | } 339 | 340 | out0 := *abi.ConvertType(out[0], new(string)).(*string) 341 | 342 | return out0, err 343 | 344 | } 345 | 346 | // Symbol is a free data retrieval call binding the contract method 0x95d89b41. 347 | // 348 | // Solidity: function symbol() view returns(string) 349 | func (_Token *TokenSession) Symbol() (string, error) { 350 | return _Token.Contract.Symbol(&_Token.CallOpts) 351 | } 352 | 353 | // Symbol is a free data retrieval call binding the contract method 0x95d89b41. 354 | // 355 | // Solidity: function symbol() view returns(string) 356 | func (_Token *TokenCallerSession) Symbol() (string, error) { 357 | return _Token.Contract.Symbol(&_Token.CallOpts) 358 | } 359 | 360 | // TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. 361 | // 362 | // Solidity: function totalSupply() view returns(uint256) 363 | func (_Token *TokenCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { 364 | var out []interface{} 365 | err := _Token.contract.Call(opts, &out, "totalSupply") 366 | 367 | if err != nil { 368 | return *new(*big.Int), err 369 | } 370 | 371 | out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) 372 | 373 | return out0, err 374 | 375 | } 376 | 377 | // TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. 378 | // 379 | // Solidity: function totalSupply() view returns(uint256) 380 | func (_Token *TokenSession) TotalSupply() (*big.Int, error) { 381 | return _Token.Contract.TotalSupply(&_Token.CallOpts) 382 | } 383 | 384 | // TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. 385 | // 386 | // Solidity: function totalSupply() view returns(uint256) 387 | func (_Token *TokenCallerSession) TotalSupply() (*big.Int, error) { 388 | return _Token.Contract.TotalSupply(&_Token.CallOpts) 389 | } 390 | 391 | // Approve is a paid mutator transaction binding the contract method 0x095ea7b3. 392 | // 393 | // Solidity: function approve(address spender, uint256 amount) returns(bool) 394 | func (_Token *TokenTransactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { 395 | return _Token.contract.Transact(opts, "approve", spender, amount) 396 | } 397 | 398 | // Approve is a paid mutator transaction binding the contract method 0x095ea7b3. 399 | // 400 | // Solidity: function approve(address spender, uint256 amount) returns(bool) 401 | func (_Token *TokenSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { 402 | return _Token.Contract.Approve(&_Token.TransactOpts, spender, amount) 403 | } 404 | 405 | // Approve is a paid mutator transaction binding the contract method 0x095ea7b3. 406 | // 407 | // Solidity: function approve(address spender, uint256 amount) returns(bool) 408 | func (_Token *TokenTransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { 409 | return _Token.Contract.Approve(&_Token.TransactOpts, spender, amount) 410 | } 411 | 412 | // DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. 413 | // 414 | // Solidity: function decreaseAllowance(address spender, uint256 subtractedValue) returns(bool) 415 | func (_Token *TokenTransactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { 416 | return _Token.contract.Transact(opts, "decreaseAllowance", spender, subtractedValue) 417 | } 418 | 419 | // DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. 420 | // 421 | // Solidity: function decreaseAllowance(address spender, uint256 subtractedValue) returns(bool) 422 | func (_Token *TokenSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { 423 | return _Token.Contract.DecreaseAllowance(&_Token.TransactOpts, spender, subtractedValue) 424 | } 425 | 426 | // DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. 427 | // 428 | // Solidity: function decreaseAllowance(address spender, uint256 subtractedValue) returns(bool) 429 | func (_Token *TokenTransactorSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { 430 | return _Token.Contract.DecreaseAllowance(&_Token.TransactOpts, spender, subtractedValue) 431 | } 432 | 433 | // IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. 434 | // 435 | // Solidity: function increaseAllowance(address spender, uint256 addedValue) returns(bool) 436 | func (_Token *TokenTransactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { 437 | return _Token.contract.Transact(opts, "increaseAllowance", spender, addedValue) 438 | } 439 | 440 | // IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. 441 | // 442 | // Solidity: function increaseAllowance(address spender, uint256 addedValue) returns(bool) 443 | func (_Token *TokenSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { 444 | return _Token.Contract.IncreaseAllowance(&_Token.TransactOpts, spender, addedValue) 445 | } 446 | 447 | // IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. 448 | // 449 | // Solidity: function increaseAllowance(address spender, uint256 addedValue) returns(bool) 450 | func (_Token *TokenTransactorSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { 451 | return _Token.Contract.IncreaseAllowance(&_Token.TransactOpts, spender, addedValue) 452 | } 453 | 454 | // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. 455 | // 456 | // Solidity: function transfer(address to, uint256 amount) returns(bool) 457 | func (_Token *TokenTransactor) Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { 458 | return _Token.contract.Transact(opts, "transfer", to, amount) 459 | } 460 | 461 | // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. 462 | // 463 | // Solidity: function transfer(address to, uint256 amount) returns(bool) 464 | func (_Token *TokenSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { 465 | return _Token.Contract.Transfer(&_Token.TransactOpts, to, amount) 466 | } 467 | 468 | // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. 469 | // 470 | // Solidity: function transfer(address to, uint256 amount) returns(bool) 471 | func (_Token *TokenTransactorSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { 472 | return _Token.Contract.Transfer(&_Token.TransactOpts, to, amount) 473 | } 474 | 475 | // TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. 476 | // 477 | // Solidity: function transferFrom(address from, address to, uint256 amount) returns(bool) 478 | func (_Token *TokenTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { 479 | return _Token.contract.Transact(opts, "transferFrom", from, to, amount) 480 | } 481 | 482 | // TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. 483 | // 484 | // Solidity: function transferFrom(address from, address to, uint256 amount) returns(bool) 485 | func (_Token *TokenSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { 486 | return _Token.Contract.TransferFrom(&_Token.TransactOpts, from, to, amount) 487 | } 488 | 489 | // TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. 490 | // 491 | // Solidity: function transferFrom(address from, address to, uint256 amount) returns(bool) 492 | func (_Token *TokenTransactorSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { 493 | return _Token.Contract.TransferFrom(&_Token.TransactOpts, from, to, amount) 494 | } 495 | 496 | // TokenApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Token contract. 497 | type TokenApprovalIterator struct { 498 | Event *TokenApproval // Event containing the contract specifics and raw log 499 | 500 | contract *bind.BoundContract // Generic contract to use for unpacking event data 501 | event string // Event name to use for unpacking event data 502 | 503 | logs chan types.Log // Log channel receiving the found contract events 504 | sub ethereum.Subscription // Subscription for errors, completion and termination 505 | done bool // Whether the subscription completed delivering logs 506 | fail error // Occurred error to stop iteration 507 | } 508 | 509 | // Next advances the iterator to the subsequent event, returning whether there 510 | // are any more events found. In case of a retrieval or parsing error, false is 511 | // returned and Error() can be queried for the exact failure. 512 | func (it *TokenApprovalIterator) Next() bool { 513 | // If the iterator failed, stop iterating 514 | if it.fail != nil { 515 | return false 516 | } 517 | // If the iterator completed, deliver directly whatever's available 518 | if it.done { 519 | select { 520 | case log := <-it.logs: 521 | it.Event = new(TokenApproval) 522 | if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { 523 | it.fail = err 524 | return false 525 | } 526 | it.Event.Raw = log 527 | return true 528 | 529 | default: 530 | return false 531 | } 532 | } 533 | // Iterator still in progress, wait for either a data or an error event 534 | select { 535 | case log := <-it.logs: 536 | it.Event = new(TokenApproval) 537 | if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { 538 | it.fail = err 539 | return false 540 | } 541 | it.Event.Raw = log 542 | return true 543 | 544 | case err := <-it.sub.Err(): 545 | it.done = true 546 | it.fail = err 547 | return it.Next() 548 | } 549 | } 550 | 551 | // Error returns any retrieval or parsing error occurred during filtering. 552 | func (it *TokenApprovalIterator) Error() error { 553 | return it.fail 554 | } 555 | 556 | // Close terminates the iteration process, releasing any pending underlying 557 | // resources. 558 | func (it *TokenApprovalIterator) Close() error { 559 | it.sub.Unsubscribe() 560 | return nil 561 | } 562 | 563 | // TokenApproval represents a Approval event raised by the Token contract. 564 | type TokenApproval struct { 565 | Owner common.Address 566 | Spender common.Address 567 | Value *big.Int 568 | Raw types.Log // Blockchain specific contextual infos 569 | } 570 | 571 | // FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. 572 | // 573 | // Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) 574 | func (_Token *TokenFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*TokenApprovalIterator, error) { 575 | 576 | var ownerRule []interface{} 577 | for _, ownerItem := range owner { 578 | ownerRule = append(ownerRule, ownerItem) 579 | } 580 | var spenderRule []interface{} 581 | for _, spenderItem := range spender { 582 | spenderRule = append(spenderRule, spenderItem) 583 | } 584 | 585 | logs, sub, err := _Token.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) 586 | if err != nil { 587 | return nil, err 588 | } 589 | return &TokenApprovalIterator{contract: _Token.contract, event: "Approval", logs: logs, sub: sub}, nil 590 | } 591 | 592 | // WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. 593 | // 594 | // Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) 595 | func (_Token *TokenFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *TokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { 596 | 597 | var ownerRule []interface{} 598 | for _, ownerItem := range owner { 599 | ownerRule = append(ownerRule, ownerItem) 600 | } 601 | var spenderRule []interface{} 602 | for _, spenderItem := range spender { 603 | spenderRule = append(spenderRule, spenderItem) 604 | } 605 | 606 | logs, sub, err := _Token.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) 607 | if err != nil { 608 | return nil, err 609 | } 610 | return event.NewSubscription(func(quit <-chan struct{}) error { 611 | defer sub.Unsubscribe() 612 | for { 613 | select { 614 | case log := <-logs: 615 | // New log arrived, parse the event and forward to the user 616 | event := new(TokenApproval) 617 | if err := _Token.contract.UnpackLog(event, "Approval", log); err != nil { 618 | return err 619 | } 620 | event.Raw = log 621 | 622 | select { 623 | case sink <- event: 624 | case err := <-sub.Err(): 625 | return err 626 | case <-quit: 627 | return nil 628 | } 629 | case err := <-sub.Err(): 630 | return err 631 | case <-quit: 632 | return nil 633 | } 634 | } 635 | }), nil 636 | } 637 | 638 | // ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. 639 | // 640 | // Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) 641 | func (_Token *TokenFilterer) ParseApproval(log types.Log) (*TokenApproval, error) { 642 | event := new(TokenApproval) 643 | if err := _Token.contract.UnpackLog(event, "Approval", log); err != nil { 644 | return nil, err 645 | } 646 | event.Raw = log 647 | return event, nil 648 | } 649 | 650 | // TokenTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the Token contract. 651 | type TokenTransferIterator struct { 652 | Event *TokenTransfer // Event containing the contract specifics and raw log 653 | 654 | contract *bind.BoundContract // Generic contract to use for unpacking event data 655 | event string // Event name to use for unpacking event data 656 | 657 | logs chan types.Log // Log channel receiving the found contract events 658 | sub ethereum.Subscription // Subscription for errors, completion and termination 659 | done bool // Whether the subscription completed delivering logs 660 | fail error // Occurred error to stop iteration 661 | } 662 | 663 | // Next advances the iterator to the subsequent event, returning whether there 664 | // are any more events found. In case of a retrieval or parsing error, false is 665 | // returned and Error() can be queried for the exact failure. 666 | func (it *TokenTransferIterator) Next() bool { 667 | // If the iterator failed, stop iterating 668 | if it.fail != nil { 669 | return false 670 | } 671 | // If the iterator completed, deliver directly whatever's available 672 | if it.done { 673 | select { 674 | case log := <-it.logs: 675 | it.Event = new(TokenTransfer) 676 | if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { 677 | it.fail = err 678 | return false 679 | } 680 | it.Event.Raw = log 681 | return true 682 | 683 | default: 684 | return false 685 | } 686 | } 687 | // Iterator still in progress, wait for either a data or an error event 688 | select { 689 | case log := <-it.logs: 690 | it.Event = new(TokenTransfer) 691 | if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { 692 | it.fail = err 693 | return false 694 | } 695 | it.Event.Raw = log 696 | return true 697 | 698 | case err := <-it.sub.Err(): 699 | it.done = true 700 | it.fail = err 701 | return it.Next() 702 | } 703 | } 704 | 705 | // Error returns any retrieval or parsing error occurred during filtering. 706 | func (it *TokenTransferIterator) Error() error { 707 | return it.fail 708 | } 709 | 710 | // Close terminates the iteration process, releasing any pending underlying 711 | // resources. 712 | func (it *TokenTransferIterator) Close() error { 713 | it.sub.Unsubscribe() 714 | return nil 715 | } 716 | 717 | // TokenTransfer represents a Transfer event raised by the Token contract. 718 | type TokenTransfer struct { 719 | From common.Address 720 | To common.Address 721 | Value *big.Int 722 | Raw types.Log // Blockchain specific contextual infos 723 | } 724 | 725 | // FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. 726 | // 727 | // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) 728 | func (_Token *TokenFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenTransferIterator, error) { 729 | 730 | var fromRule []interface{} 731 | for _, fromItem := range from { 732 | fromRule = append(fromRule, fromItem) 733 | } 734 | var toRule []interface{} 735 | for _, toItem := range to { 736 | toRule = append(toRule, toItem) 737 | } 738 | 739 | logs, sub, err := _Token.contract.FilterLogs(opts, "Transfer", fromRule, toRule) 740 | if err != nil { 741 | return nil, err 742 | } 743 | return &TokenTransferIterator{contract: _Token.contract, event: "Transfer", logs: logs, sub: sub}, nil 744 | } 745 | 746 | // WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. 747 | // 748 | // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) 749 | func (_Token *TokenFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *TokenTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { 750 | 751 | var fromRule []interface{} 752 | for _, fromItem := range from { 753 | fromRule = append(fromRule, fromItem) 754 | } 755 | var toRule []interface{} 756 | for _, toItem := range to { 757 | toRule = append(toRule, toItem) 758 | } 759 | 760 | logs, sub, err := _Token.contract.WatchLogs(opts, "Transfer", fromRule, toRule) 761 | if err != nil { 762 | return nil, err 763 | } 764 | return event.NewSubscription(func(quit <-chan struct{}) error { 765 | defer sub.Unsubscribe() 766 | for { 767 | select { 768 | case log := <-logs: 769 | // New log arrived, parse the event and forward to the user 770 | event := new(TokenTransfer) 771 | if err := _Token.contract.UnpackLog(event, "Transfer", log); err != nil { 772 | return err 773 | } 774 | event.Raw = log 775 | 776 | select { 777 | case sink <- event: 778 | case err := <-sub.Err(): 779 | return err 780 | case <-quit: 781 | return nil 782 | } 783 | case err := <-sub.Err(): 784 | return err 785 | case <-quit: 786 | return nil 787 | } 788 | } 789 | }), nil 790 | } 791 | 792 | // ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. 793 | // 794 | // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) 795 | func (_Token *TokenFilterer) ParseTransfer(log types.Log) (*TokenTransfer, error) { 796 | event := new(TokenTransfer) 797 | if err := _Token.contract.UnpackLog(event, "Transfer", log); err != nil { 798 | return nil, err 799 | } 800 | event.Raw = log 801 | return event, nil 802 | } 803 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module mevcopytrader 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/ethereum/go-ethereum v1.11.6 7 | github.com/fatih/color v1.7.0 8 | ) 9 | 10 | require ( 11 | github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect 12 | github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect 13 | github.com/deckarep/golang-set/v2 v2.1.0 // indirect 14 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect 15 | github.com/fsnotify/fsnotify v1.6.0 // indirect 16 | github.com/go-ole/go-ole v1.2.1 // indirect 17 | github.com/go-stack/stack v1.8.1 // indirect 18 | github.com/google/uuid v1.3.0 // indirect 19 | github.com/gorilla/websocket v1.4.2 // indirect 20 | github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect 21 | github.com/mattn/go-colorable v0.1.13 // indirect 22 | github.com/mattn/go-isatty v0.0.16 // indirect 23 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect 24 | github.com/tklauser/go-sysconf v0.3.5 // indirect 25 | github.com/tklauser/numcpus v0.2.2 // indirect 26 | golang.org/x/crypto v0.1.0 // indirect 27 | golang.org/x/sys v0.6.0 // indirect 28 | gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect 29 | ) 30 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= 2 | github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= 3 | github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= 4 | github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= 5 | github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= 6 | github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= 7 | github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= 8 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= 9 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= 10 | github.com/ethereum/go-ethereum v1.11.6 h1:2VF8Mf7XiSUfmoNOy3D+ocfl9Qu8baQBrCNbo2CXQ8E= 11 | github.com/ethereum/go-ethereum v1.11.6/go.mod h1:+a8pUj1tOyJ2RinsNQD4326YS+leSoKGiG/uVVb0x6Y= 12 | github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= 13 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 14 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 15 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 16 | github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= 17 | github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= 18 | github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= 19 | github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= 20 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 21 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 22 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 23 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 24 | github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= 25 | github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= 26 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 27 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 28 | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= 29 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 30 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= 31 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 32 | github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= 33 | github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= 34 | github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= 35 | github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= 36 | golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= 37 | golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 38 | golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 39 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 40 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 41 | golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= 42 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 43 | gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= 44 | gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= 45 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // @author - deltartificial 2 | package main 3 | 4 | import ( 5 | "context" 6 | "fmt" 7 | "log" 8 | "math/big" 9 | "sync" 10 | 11 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 12 | "github.com/ethereum/go-ethereum/common" 13 | "github.com/ethereum/go-ethereum/core/types" 14 | "github.com/ethereum/go-ethereum/crypto" 15 | "github.com/ethereum/go-ethereum/ethclient" 16 | "github.com/fatih/color" 17 | 18 | token "mevcopytrader/contracts_erc20" 19 | ) 20 | 21 | var ( 22 | WssRpcNode = "" 23 | SandwichBotEOAAddress = common.HexToAddress("0xae2fc483527b8ef99eb5d9b44875f005ba1fae13") 24 | SandwitchBotContractAddress = common.HexToAddress("0x6b75d8AF000000e20B7a7DDf000Ba900b4009A80") 25 | transferFnSignature = crypto.Keccak256Hash([]byte("Transfer(address,address,uint256)")) 26 | callOpts = &bind.CallOpts{} 27 | tokenCache = make(map[common.Address]string) 28 | mu sync.Mutex 29 | cyan = color.New(color.FgCyan, color.Bold).SprintFunc() 30 | green = color.New(color.FgGreen, color.Bold).SprintFunc() 31 | yellow = color.New(color.FgYellow, color.Bold).SprintFunc() 32 | ) 33 | 34 | const workerCount = 10 35 | 36 | func main() { 37 | client, err := ethclient.Dial(WssRpcNode) 38 | if err != nil { 39 | log.Fatal(err) 40 | } 41 | 42 | headers := make(chan *types.Header, 10) 43 | sub, err := client.SubscribeNewHead(context.Background(), headers) 44 | if err != nil { 45 | log.Fatal(err) 46 | } 47 | 48 | chainID, err := client.NetworkID(context.Background()) 49 | if err != nil { 50 | log.Fatal(err) 51 | } 52 | 53 | blocks := make(chan *types.Block, 100) 54 | var wg sync.WaitGroup 55 | wg.Add(workerCount) 56 | for i := 0; i < workerCount; i++ { 57 | go worker(client, chainID, SandwichBotEOAAddress, blocks, &wg) 58 | } 59 | 60 | for { 61 | select { 62 | case err := <-sub.Err(): 63 | log.Fatal(err) 64 | case header := <-headers: 65 | block, err := client.BlockByHash(context.Background(), header.Hash()) 66 | if err != nil { 67 | log.Fatal(err) 68 | } 69 | 70 | fmt.Printf("%s Block Time: %d, Block Number: %d, Block Hash: %s\n", cyan("[INFO]"), block.Time(), block.Number().Uint64(), block.Hash().Hex()) 71 | 72 | blocks <- block 73 | } 74 | } 75 | } 76 | 77 | func worker(client *ethclient.Client, chainID *big.Int, SandwichBotEOAAddress common.Address, blocks <-chan *types.Block, wg *sync.WaitGroup) { 78 | defer wg.Done() 79 | for block := range blocks { 80 | for _, tx := range block.Transactions() { 81 | processTransaction(client, chainID, SandwichBotEOAAddress, tx, block.Number()) 82 | } 83 | } 84 | } 85 | 86 | func processTransaction(client *ethclient.Client, chainID *big.Int, SandwichBotEOAAddress common.Address, tx *types.Transaction, blockNumber *big.Int) { 87 | signer := types.NewLondonSigner(chainID) 88 | sender, err := types.Sender(signer, tx) 89 | if err != nil { 90 | log.Fatal("3", err) 91 | } 92 | if sender == SandwichBotEOAAddress { 93 | receipt, err := client.TransactionReceipt(context.Background(), tx.Hash()) 94 | if err != nil { 95 | log.Fatal(err) 96 | } 97 | 98 | for _, vLog := range receipt.Logs { 99 | if vLog.Topics[0] == transferFnSignature { 100 | eventAddress := vLog.Address 101 | 102 | tokenNameAddress, err := getTokenName(client, eventAddress) 103 | if err != nil { 104 | fmt.Println(err) 105 | } 106 | 107 | fmt.Printf("%s (ERC20) - Address: %s (%v)\n", yellow("[>]"), eventAddress, yellow(tokenNameAddress)) 108 | 109 | blockDetermined := new(big.Int).Sub(blockNumber, big.NewInt(3)) 110 | 111 | balanceAtBlock, err := getTokenBalanceAtBlock(client, eventAddress, SandwitchBotContractAddress, blockDetermined) 112 | if err != nil { 113 | log.Fatal(err) 114 | } 115 | 116 | if balanceAtBlock.Cmp(big.NewInt(0)) == 0 { 117 | fmt.Printf("%s NEW ERC-20 BUY at block %v : %s (%v)\n", green("[FOUND]"), blockDetermined, eventAddress, tokenNameAddress) 118 | } 119 | } 120 | } 121 | } 122 | } 123 | 124 | func getTokenName(client *ethclient.Client, tokenAddress common.Address) (string, error) { 125 | mu.Lock() 126 | if name, ok := tokenCache[tokenAddress]; ok { 127 | mu.Unlock() 128 | return name, nil 129 | } 130 | mu.Unlock() 131 | 132 | instance, err := token.NewToken(tokenAddress, client) 133 | if err != nil { 134 | return "", err 135 | } 136 | 137 | name, err := instance.Name(callOpts) 138 | if err != nil { 139 | return "", err 140 | } 141 | 142 | mu.Lock() 143 | tokenCache[tokenAddress] = name 144 | mu.Unlock() 145 | 146 | return name, nil 147 | } 148 | 149 | func getTokenBalanceAtBlock(client *ethclient.Client, tokenAddress common.Address, addressToCheck common.Address, blockNumber *big.Int) (*big.Int, error) { 150 | instance, err := token.NewToken(tokenAddress, client) 151 | if err != nil { 152 | return nil, err 153 | } 154 | 155 | callOpts.BlockNumber = blockNumber 156 | 157 | balance, err := instance.BalanceOf(callOpts, addressToCheck) 158 | if err != nil { 159 | return nil, err 160 | } 161 | 162 | return balance, nil 163 | } 164 | --------------------------------------------------------------------------------