github.com/theQRL/go-zond@v0.2.1/accounts/abi/method.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package abi 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/theQRL/go-zond/crypto" 24 ) 25 26 // FunctionType represents different types of functions a contract might have. 27 type FunctionType int 28 29 const ( 30 // Constructor represents the constructor of the contract. 31 // The constructor function is called while deploying a contract. 32 Constructor FunctionType = iota 33 // Fallback represents the fallback function. 34 // This function is executed if no other function matches the given function 35 // signature and no receive function is specified. 36 Fallback 37 // Receive represents the receive function. 38 // This function is executed on plain Ether transfers. 39 Receive 40 // Function represents a normal function. 41 Function 42 ) 43 44 // Method represents a callable given a `Name` and whether the method is a constant. 45 // If the method is `Const` no transaction needs to be created for this 46 // particular Method call. It can easily be simulated using a local VM. 47 // For example a `Balance()` method only needs to retrieve something 48 // from the storage and therefore requires no Tx to be sent to the 49 // network. A method such as `Transact` does require a Tx and thus will 50 // be flagged `false`. 51 // Input specifies the required input parameters for this gives method. 52 type Method struct { 53 // Name is the method name used for internal representation. It's derived from 54 // the raw name and a suffix will be added in the case of a function overload. 55 // 56 // e.g. 57 // These are two functions that have the same name: 58 // * foo(int,int) 59 // * foo(uint,uint) 60 // The method name of the first one will be resolved as foo while the second one 61 // will be resolved as foo0. 62 Name string 63 RawName string // RawName is the raw method name parsed from ABI 64 65 // Type indicates whether the method is a special fallback 66 Type FunctionType 67 68 // StateMutability indicates the mutability state of method, 69 // the default value is nonpayable. It can be empty if the abi 70 // is generated by legacy compiler. 71 StateMutability string 72 73 Inputs Arguments 74 Outputs Arguments 75 str string 76 // Sig returns the methods string signature according to the ABI spec. 77 // e.g. function foo(uint32 a, int b) = "foo(uint32,int256)" 78 // Please note that "int" is substitute for its canonical representation "int256" 79 Sig string 80 // ID returns the canonical representation of the method's signature used by the 81 // abi definition to identify method names and types. 82 ID []byte 83 } 84 85 // NewMethod creates a new Method. 86 // A method should always be created using NewMethod. 87 // It also precomputes the sig representation and the string representation 88 // of the method. 89 func NewMethod(name string, rawName string, funType FunctionType, mutability string, isConst, isPayable bool, inputs Arguments, outputs Arguments) Method { 90 var ( 91 types = make([]string, len(inputs)) 92 inputNames = make([]string, len(inputs)) 93 outputNames = make([]string, len(outputs)) 94 ) 95 for i, input := range inputs { 96 inputNames[i] = fmt.Sprintf("%v %v", input.Type, input.Name) 97 types[i] = input.Type.String() 98 } 99 for i, output := range outputs { 100 outputNames[i] = output.Type.String() 101 if len(output.Name) > 0 { 102 outputNames[i] += fmt.Sprintf(" %v", output.Name) 103 } 104 } 105 // calculate the signature and method id. Note only function 106 // has meaningful signature and id. 107 var ( 108 sig string 109 id []byte 110 ) 111 if funType == Function { 112 sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ",")) 113 id = crypto.Keccak256([]byte(sig))[:4] 114 } 115 // Extract meaningful state mutability of hyperion method. 116 // If it's default value, never print it. 117 state := mutability 118 if state == "nonpayable" { 119 state = "" 120 } 121 if state != "" { 122 state = state + " " 123 } 124 identity := fmt.Sprintf("function %v", rawName) 125 switch funType { 126 case Fallback: 127 identity = "fallback" 128 case Receive: 129 identity = "receive" 130 case Constructor: 131 identity = "constructor" 132 } 133 str := fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputNames, ", "), state, strings.Join(outputNames, ", ")) 134 135 return Method{ 136 Name: name, 137 RawName: rawName, 138 Type: funType, 139 StateMutability: mutability, 140 Inputs: inputs, 141 Outputs: outputs, 142 str: str, 143 Sig: sig, 144 ID: id, 145 } 146 } 147 148 func (method Method) String() string { 149 return method.str 150 } 151 152 // IsConstant returns the indicator whether the method is read-only. 153 func (method Method) IsConstant() bool { 154 return method.StateMutability == "view" || method.StateMutability == "pure" 155 } 156 157 // IsPayable returns the indicator whether the method can process 158 // plain ether transfers. 159 func (method Method) IsPayable() bool { 160 return method.StateMutability == "payable" 161 }