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