pragma solidity ^0.4.22;
contract Testing {
function setName(bytes32 firstName , bytes32 lastName) public returns(bool) {
Sample _test = new Sample(firstName);
_test.addLastName(firstName, lastName);
return true;
}
}
contract Sample {
address a;
bytes32 firstName;
bytes32 lastName;
constructor(bytes32 _firstName) public {
firstName = _firstName;
}
modifier onlyBy(bytes32 _firstName) {
require(
firstName == _firstName,
"Error"
);
_;
}
function addLastName(bytes32 firstName, bytes32 _name) public onlyBy(firstName) returns(bool) {
lastName = _name;
return true;
}
}
I am getting this error
(node:12667) UnhandledPromiseRejectionWarning: Error: Transaction has been reverted by the EVM:
{
"blockHash":"0xe709d446057c70ba4928424a71e072aa0b144461ceea0fc535849cd05c7b1cda",
"blockNumber":4301,
"contractAddress":null,
"cumulativeGasUsed":62775,
"from":"0x112fda795ce61992653b8775597a9152ee776e4c",
"gasUsed":62775,
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status":false,
"to":"0x41e864e68ecebe2fd69cea1eed49b5fc516e9af9",
"transactionHash":"0x33b3921491631d4e2d35a3887858f21a3c02b2dd552b624bb243e2c33f6c4e86",
"transactionIndex":0,
"events":{
}
}
-
What do you mean exactly? BTW the EVM is deterministic and fully sequential– BriomkezCommented Sep 11, 2018 at 16:13
-
The above code is working fine sometimes and sometimes it is reverting the transaction. Even after removing the modifier also it is reverting. I am not sure whether the call is going sequentially.– MallRoyCommented Sep 11, 2018 at 16:53
-
Which exception do you get when "it goes wrong"?– BriomkezCommented Sep 11, 2018 at 16:54
-
I am getting the transaction receipt with this error object , transaction is reverted by the evm and the corresponding block details like transaction hash, block number and other details of block– MallRoyCommented Sep 12, 2018 at 1:36
-
Which error object? Can you edit your question and put the error in the question? BTW Each time you call testing you create a new contract. This operation is not so cheap, so it is possible that you run out of gas...– BriomkezCommented Sep 12, 2018 at 7:13
2 Answers
PREMISE
As already said, the EVM execute fully deterministically and sequentially.
ANSWER
You get the exception from javascript because the execution runs out of gas. You can guess that because the gas used is the same amount of "gasLimit". This means that either you allocate too low gas or alternatively, you use too much gas for the execution. I propend for the latter because each time you call test you are deploying a new contract in the network with
Sample _test = new Sample(firstName);
.
When you call new
under the hood it uses a CREATE
instruction. It costs 32000 gas. In addition, you have also to pay 200 gas for each byte stored on the blockchain, i.e. the persistent code of the contract. In addition you pay for the executed instructions and for the memory used during the execution. Moreover, the intrinsic cost for a transaction is 21000 units of gas. You also pay 4 gas units for each input byte that is 0 and 68 gas units for each input byte that is not equal to 0.
So let's sum up the amount of gas used:
21000 + |input_price| + 32000 + |o|*200 + |amount of gas for the rest of execution|
Where |o| is the size of the code that will persist on the blockchain.
You can easily see that 62775, is too low to grant the whole execution.
All smart contracts in Ethereum are executed synchronously - that includes external/contract-to-contract calls!
If your transaction calls a contract that itself calls 5 other contracts, those calls will all be executed before any other transactions (from other users) are executed.
So, if your transaction is the first transaction included in a block, all the results of your transaction will occur before the execution of any of the other transactions in that block start.