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