【发布时间】:2021-03-19 17:24:09
【问题描述】:
我尝试使用 python-solidity-parser (https://github.com/ConsenSys/python-solidity-parser) 解析以下代码
pragma solidity ^0.4.13;
contract someContract {
mapping(address => uint) balances;
function deposit() payable {
balances[msg.sender] += msg.value;
}
function withdrawOkayish(uint amount) {
if(balances[msg.sender] >= amount) {
balances[msg.sender] -= amount; if(!msg.sender.send(amount)) { throw; }
}
}
function withdrawBad2(uint amount) {
if(balances[msg.sender] >= amount) {
balances[msg.sender] -= amount;
if(!msg.sender.call.gas(2500000).value(amount)()) { throw; }
}
}
}
它产生以下输出
{'children': [{'name': 'solidity',
'type': 'PragmaDirective',
'value': '^0.4.13'},
{'baseContracts': [],
'kind': 'contract',
'name': 'someContract',
'subNodes': [{'initialValue': None,
'type': 'StateVariableDeclaration',
'variables': [{'expression': None,
'isDeclaredConst': False,
'isIndexed': False,
'isStateVar': True,
'name': 'balances',
'type': 'VariableDeclaration',
'typeName': {'keyType': {'name': 'address',
'type': 'ElementaryTypeName'},
'type': 'Mapping',
'valueType': {'name': 'uint',
'type': 'ElementaryTypeName'}},
'visibility': 'default'}]},
{'body': {'statements': [{'expression': {'left': {'base': {'name': 'balances',
'type': 'Identifier'},
'index': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'type': 'IndexAccess'},
'operator': '+=',
'right': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'value',
'type': 'MemberAccess'},
'type': 'BinaryOperation'},
'type': 'ExpressionStatement'}],
'type': 'Block'},
'isConstructor': False,
'modifiers': [],
'name': 'deposit',
'parameters': {'parameters': [],
'type': 'ParameterList'},
'returnParameters': [],
'stateMutability': 'payable',
'type': 'FunctionDefinition',
'visibility': 'default'},
{'body': {'statements': [{'FalseBody': None,
'TrueBody': {'statements': [{'expression': {'left': {'base': {'name': 'balances',
'type': 'Identifier'},
'index': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'type': 'IndexAccess'},
'operator': '-=',
'right': {'name': 'amount',
'type': 'Identifier'},
'type': 'BinaryOperation'},
'type': 'ExpressionStatement'},
{'FalseBody': None,
'TrueBody': {'statements': [';'],
'type': 'Block'},
'condition': {'isPrefix': True,
'operator': '!',
'subExpression': {'arguments': [{'name': 'amount',
'type': 'Identifier'}],
'expression': {'expression': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'memberName': 'send',
'type': 'MemberAccess'},
'names': [],
'type': 'FunctionCall'},
'type': 'UnaryOperation'},
'type': 'IfStatement'}],
'type': 'Block'},
'condition': {'left': {'base': {'name': 'balances',
'type': 'Identifier'},
'index': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'type': 'IndexAccess'},
'operator': '>=',
'right': {'name': 'amount',
'type': 'Identifier'},
'type': 'BinaryOperation'},
'type': 'IfStatement'}],
'type': 'Block'},
'isConstructor': False,
'modifiers': [],
'name': 'withdrawOkayish',
'parameters': {'parameters': [{'isIndexed': False,
'isStateVar': False,
'name': 'amount',
'storageLocation': None,
'type': 'Parameter',
'typeName': {'name': 'uint',
'type': 'ElementaryTypeName'}}],
'type': 'ParameterList'},
'returnParameters': [],
'stateMutability': None,
'type': 'FunctionDefinition',
'visibility': 'default'},
{'body': {'statements': [{'FalseBody': None,
'TrueBody': {'statements': [{'expression': {'left': {'base': {'name': 'balances',
'type': 'Identifier'},
'index': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'type': 'IndexAccess'},
'operator': '-=',
'right': {'name': 'amount',
'type': 'Identifier'},
'type': 'BinaryOperation'},
'type': 'ExpressionStatement'},
{'FalseBody': None,
'TrueBody': {'statements': [';'],
'type': 'Block'},
'condition': {'isPrefix': True,
'operator': '!',
'subExpression': {'arguments': [],
'expression': {'arguments': [{'name': 'amount',
'type': 'Identifier'}],
'expression': {'expression': {'arguments': [{'number': '2500000',
'subdenomination': None,
'type': 'NumberLiteral'}],
'expression': {'expression': {'expression': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'memberName': 'call',
'type': 'MemberAccess'},
'memberName': 'gas',
'type': 'MemberAccess'},
'names': [],
'type': 'FunctionCall'},
'memberName': 'value',
'type': 'MemberAccess'},
'names': [],
'type': 'FunctionCall'},
'names': [],
'type': 'FunctionCall'},
'type': 'UnaryOperation'},
'type': 'IfStatement'}],
'type': 'Block'},
'condition': {'left': {'base': {'name': 'balances',
'type': 'Identifier'},
'index': {'expression': {'name': 'msg',
'type': 'Identifier'},
'memberName': 'sender',
'type': 'MemberAccess'},
'type': 'IndexAccess'},
'operator': '>=',
'right': {'name': 'amount',
'type': 'Identifier'},
'type': 'BinaryOperation'},
'type': 'IfStatement'}],
'type': 'Block'},
'isConstructor': False,
'modifiers': [],
'name': 'withdrawBad2',
'parameters': {'parameters': [{'isIndexed': False,
'isStateVar': False,
'name': 'amount',
'storageLocation': None,
'type': 'Parameter',
'typeName': {'name': 'uint',
'type': 'ElementaryTypeName'}}],
'type': 'ParameterList'},
'returnParameters': [],
'stateMutability': None,
'type': 'FunctionDefinition',
'visibility': 'default'}],
'type': 'ContractDefinition'}],
'type': 'SourceUnit'}
我发现它不处理 throw 关键字。两者都 if case 块仅包含';'。 我无法找到解决此问题的方法。有什么办法可以解决这个问题。
在此处创建问题:https://github.com/ConsenSys/python-solidity-parser/issues/11
【问题讨论】:
-
这里不是 python 人,但我确实花了一点时间来提取语法并根据您的输入运行它。我可以确认该项目中使用的 ANTLR 语法确实找到了
throw语句并将其包含在它的解析树中。所以问题将出在 ANTLR 语法以外的地方。
标签: python json parsing antlr solidity