1 #ifndef CONTRACTABI_H
2 #define CONTRACTABI_H
3 #include <string>
4 #include <vector>
5 #include <map>
6 
7 
8 /**
9  * @brief The ParameterType class Decode the api parameter type,
10  * provide more informations about the data type that can be used for encoding and decoding.
11  */
12 class ParameterType
13 {
14 public:
15     /**
16      * @brief The Type enum ABI data types
17      */
18     enum Type
19     {
20         abi_none,
21         abi_bytes,
22         abi_string,
23         abi_uint,
24         abi_int,
25         abi_address,
26         abi_bool,
27         abi_fixed,
28         abi_ufixed,
29         abi_function
30     };
31 
32     /**
33      * @brief ParameterType Constructor
34      */
35     ParameterType(const std::string& _type = "");
36 
37     /**
38      * @brief determine Determine the type from the string
39      * @param _type String representation of the type
40      * @return true: type determined, false: type not determined
41      */
42     bool determine(const std::string& _type);
43 
44     /**
45      * @brief wholeBits Get the number of bits for the whole part of the number
46      * @return Number of bits
47      */
48     size_t wholeBits() const;
49 
50     /**
51      * @brief decimalBits Get the number of bits for the decimal part of the number
52      * @return Number of bits
53      */
54     size_t decimalBits() const;
55 
56     /**
57      * @brief totalBytes Get the total size in bytes
58      * @return Number of bytes
59      */
60     size_t totalBytes() const;
61 
62     /**
63      * @brief length Length of the list, applicable for list only
64      * @return Length of the list
65      */
66     size_t length() const;
67 
68     /**
69      * @brief isList Is the data type list
70      * @return true: is list, false: not list
71      */
72     bool isList() const;
73 
74     /**
75      * @brief isDynamic Check if the type is dynamic.
76      * Dynamic type include pointer to the location where the content starts.
77      * @return true: is dynamic, false: is static
78      */
79     bool isDynamic() const;
80 
81     /**
82      * @brief isValid Check if the type is valid
83      * @return true: is valid, false: not valid
84      */
85     bool isValid() const;
86 
87     /**
88      * @brief canonical Get the canonical type
89      * @return String representation of the type
90      */
91     const std::string& canonical() const;
92 
93     /**
94      * @brief type Get the type
95      * @return Decoded type
96      */
97     Type type() const;
98 
99 private:
100     /**
101      * @brief clean Set the value to the defaults
102      */
103     void clean();
104 
105     Type m_type;
106     int m_whole;
107     int m_decimal;
108     int m_length;
109     bool m_isList;
110     bool m_valid;
111     std::string m_canonical;
112 };
113 
114 class ParameterABI
115 {
116 public:
117     enum ErrorType
118     {
119         Ok = 0,
120         UnsupportedABI,
121         EncodingError,
122         DecodingError
123     };
124 
125     ParameterABI(const std::string& _name = "", const std::string& _type = "", bool _indexed = false);
126     ~ParameterABI();
127     bool abiIn(const std::vector<std::string> &value, std::string &data, std::map<int, std::string>& mapDynamic) const;
128     bool abiOut(const std::string &data, size_t& pos, std::vector<std::string> &value) const;
129     const ParameterType &decodeType() const;
130 
131     std::string name; // The name of the parameter;
132     std::string type; // The canonical type of the parameter.
133     bool indexed; // True if the field is part of the log's topics, false if it one of the log's data segment.
134     // Indexed is only used with event function
135 
136     ErrorType lastError() const;
137 
138 private:
139     bool abiInBasic(ParameterType::Type abiType, std::string value, std::string &data) const;
140     bool abiOutBasic(ParameterType::Type abiType, const std::string &data, size_t &pos, std::string &value) const;
141     void addDynamic(const std::string& paramData, std::string &data, std::map<int, std::string>& mapDynamic) const;
142 
143 
144     mutable ParameterType m_decodeType;
145     mutable ErrorType m_lastError;
146 };
147 
148 class FunctionABI
149 {
150 public:
151     FunctionABI(const std::string& _name = "",
152                 const std::string& _type = "function",
153                 const std::vector<ParameterABI>& _inputs = std::vector<ParameterABI>(),
154                 const std::vector<ParameterABI>& _outputs = std::vector<ParameterABI>(),
155                 bool _payable = false,
156                 bool _constant = false,
157                 bool _anonymous = false);
158 
159     bool abiIn(const std::vector<std::vector<std::string>>& values, std::string& data, std::vector<ParameterABI::ErrorType>& errors) const;
160 
161     bool abiOut(const std::string& data, std::vector<std::vector<std::string>>& values, std::vector<ParameterABI::ErrorType>& errors) const;
162 
163     bool abiOut(const std::vector<std::string>& topics, const std::string& data, std::vector<std::vector<std::string>>& values, std::vector<ParameterABI::ErrorType>& errors) const;
164 
165     std::string selector() const;
166 
167     int numIndexed() const;
168 
169     static std::string defaultSelector();
170 
171     std::string name; // The name of the function;
172     std::string type; // Function types: "function", "constructor", "fallback" or "event"
173     std::vector<ParameterABI> inputs; // Array of input parameters
174     std::vector<ParameterABI> outputs; // Array of output parameters, can be omitted if function doesn't return
175     bool payable; // True if function accepts ether, defaults to false.
176     bool constant; // True if function is specified to not modify blockchain state.
177     bool anonymous; // True if the event was declared as anonymous.
178     std::string stateMutability; // Function state mutability: "pure", "view", "nonpayable" or "payable"
179 
180     // Constructor and fallback function never have name or outputs.
181     // Fallback function doesn't have inputs either.
182     // Event function is the only one that have anonymous.
183     // Sending non-zero ether to non-payable function will throw.
184     // Type can be omitted, defaulting to "function".
185 
186     void cache();
187 
188 private:
189     void processDynamicParams(const std::map<int, std::string>& mapDynamic, std::string& data) const;
190     bool cached;
191     std::string cacheSelector;
192 };
193 
194 class ContractABI
195 {
196 public:
197     ContractABI();
198     ContractABI(const std::string& json_data);
199     bool loads(const std::string& json_data);
200     void clean();
201 
202     std::vector<FunctionABI> functions;
203     FunctionABI operator[](std::string name) const;
204 };
205 
206 #endif // CONTRACTABI_H
207