-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib_external_call.sol
44 lines (33 loc) · 1.56 KB
/
lib_external_call.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
pragma solidity 0.5.4;
library ExternalCall {
address constant elv_precomp_extern_call = address(253);
bytes4 constant sigIdString = bytes4(keccak256("callString(string,address,uint256,bytes)"));
bytes4 constant sigIdUint = bytes4(keccak256("callUint(string,address,uint256,bytes)"));
bytes4 constant sigIdAddress = bytes4(keccak256("callAddress(string,address,uint256,bytes)"));
function callUint(string memory _config, address _extAddr, uint256 _blockNum, bytes memory _params) internal view returns (uint256 ret) {
bytes4 sig = sigIdUint;
address callAddr = elv_precomp_extern_call;
bytes32 truncConfig;
uint paramsLen = _params.length;
uint allLen = 4 + 96 + paramsLen; // 4bytes + truncated config + address + block num + params bytes length
assembly {
let x := mload(0x40) // Find empty storage location using "free memory pointer"
mstore(x, sig) // Place signature at beginning of empty storage
truncConfig := mload(add(_config, 32))
mstore(add(x, 4), truncConfig)
mstore(add(x, 36), _extAddr)
mstore(add(x, 68), _blockNum)
for { let i := 0 } lt(i, paramsLen) { i := add(i, 32) } {
mstore(add(x, add(100,i)), mload(add(add(_params, 32), i)))
}
let res := staticcall(0, callAddr, x, allLen, x, 32)
switch res
case 0 {
revert(0, 0)
}
default {
ret := mload(x)
}
}
}
}