Parse Polygon Smart Contract using Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module poly | |
go 1.18 | |
require github.com/ethereum/go-ethereum v1.10.21 | |
require ( | |
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect | |
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect | |
github.com/deckarep/golang-set v1.8.0 // indirect | |
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect | |
github.com/go-ole/go-ole v1.2.1 // indirect | |
github.com/go-stack/stack v1.8.0 // indirect | |
github.com/gorilla/websocket v1.4.2 // indirect | |
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect | |
github.com/tklauser/go-sysconf v0.3.5 // indirect | |
github.com/tklauser/numcpus v0.2.2 // indirect | |
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect | |
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect | |
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"setParent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"sig","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"data","type":"bytes32"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"transferWithSig","outputs":[{"internalType":"address","name":"from","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_childChain","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"parent","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"parentOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"ecrecovery","outputs":[{"internalType":"address","name":"result","type":"address"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"networkId","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_TOKEN_TRANSFER_ORDER_SCHEMA_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"disabledHashes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenIdOrAmount","type":"uint256"},{"internalType":"bytes32","name":"data","type":"bytes32"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"getTokenTransferOrderHash","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAINID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_DOMAIN_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_DOMAIN_SCHEMA_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"input1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"output1","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"input1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"output1","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"input1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"input2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"output1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"output2","type":"uint256"}],"name":"LogTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"input1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"input2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"output1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"output2","type":"uint256"}],"name":"LogFeeTransfer","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"}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ go build . && ./poly --rpc https://virulent-fluent-isle.matic.quiknode.pro/625d8404f145726303e9637515d142dc12c630a8/ --block 31742819 | |
Chain ID: 137 Latest: 31747503 | |
Found method: name | |
Found method: owner | |
Found method: transfer | |
Found method: disabledHashes | |
Found method: parentOwner | |
Found method: networkId | |
Found method: getTokenTransferOrderHash | |
Found method: withdraw | |
Found method: initialize | |
Found method: CHAINID | |
Found method: parent | |
Found method: renounceOwnership | |
Found method: symbol | |
Found method: token | |
Found method: transferWithSig | |
Found method: balanceOf | |
Found method: ecrecovery | |
Found method: EIP712_DOMAIN_SCHEMA_HASH | |
Found method: currentSupply | |
Found method: isOwner | |
Found method: EIP712_DOMAIN_HASH | |
Found method: totalSupply | |
Found method: EIP712_TOKEN_TRANSFER_ORDER_SCHEMA_HASH | |
Found method: setParent | |
Found method: decimals | |
Found method: deposit | |
Found method: transferOwnership | |
All methods found | |
Found 65 transactions in block: 31742819 | |
Txn Hash: 0x14bfd28ca9c17b60126d9f48f59789b19afc1c117dc6bbb291ff0a961e72db7c Method: withdraw Inputs: map[amount:+50000000000000000000] | |
Done parsing Block: 31742819. Found 1 txns involving contract. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"context" | |
"flag" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"math/big" | |
"github.com/ethereum/go-ethereum/accounts/abi" | |
"github.com/ethereum/go-ethereum/ethclient" | |
) | |
var path = flag.String("rpc", "", "Polygon Bor JSON RPC path") | |
var blockId = flag.Int64("block", 31740481, "Fetch this block from Polygon") | |
// https://polygonscan.com/address/0x0000000000000000000000000000000000001010 | |
const contractAddr = "0x0000000000000000000000000000000000001010" | |
func Check(err error) { | |
if err != nil { | |
log.Fatalf("Got error: %v", err) | |
} | |
} | |
func main() { | |
flag.Parse() | |
client, err := ethclient.Dial(*path) | |
if err != nil { | |
log.Fatal(err) | |
} | |
chainID, err := client.NetworkID(context.Background()) | |
if err != nil { | |
log.Fatal(err) | |
} | |
header, err := client.HeaderByNumber(context.Background(), nil) | |
if err != nil { | |
log.Fatal(err) | |
} | |
fmt.Printf("Chain ID: %d Latest: %08d\n", chainID.Uint64(), header.Number) | |
fdata, err := ioutil.ReadFile("mrc20.abi") | |
Check(err) | |
contractAbi, err := abi.JSON(bytes.NewReader(fdata)) | |
Check(err) | |
for m := range contractAbi.Methods { | |
fmt.Printf("Found method: %s\n", m) | |
} | |
fmt.Printf("All methods found\n\n") | |
bno := new(big.Int).SetInt64(*blockId) | |
block, err := client.BlockByNumber(context.Background(), bno) | |
Check(err) | |
fmt.Printf("Found %d transactions in block: %d\n\n", len(block.Transactions()), *blockId) | |
var valid int | |
for _, tx := range block.Transactions() { | |
// Only pick the txns which are interfacing with the right contract. | |
if tx.To() == nil || tx.To().String() != contractAddr { | |
continue | |
} | |
input := tx.Data() | |
if len(input) < 4 { | |
fmt.Printf("Input data of size: %d\n", len(input)) | |
continue | |
} | |
valid++ | |
m, err := contractAbi.MethodById(input[:4]) // first 4 bytes = method id. | |
Check(err) | |
in := make(map[string]interface{}) | |
Check(m.Inputs.UnpackIntoMap(in, input[4:])) | |
fmt.Printf("Txn Hash: %s Method: %s Inputs: %+v\n", tx.Hash().String(), m.Name, in) | |
} | |
fmt.Printf("\nDone parsing Block: %d. Found %d txns involving contract.\n", *blockId, valid) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment