I have created a contract where I am taking 2 Hashes from the user and trying to compare them both which in return would give a boolean value of true or false. It works good on remix but when I try to run the contract on Mist the compareString function just shows a message "NO". here is my code.
pragma solidity ^0.4.18;
contract Hash {
string fhash;
string comphash;
event Instructor(string _fhash);
event Instructors(string _comphash);
function setinstructor(string _fhash) public {
fhash = _fhash;
emit Instructor(_fhash);
}
function getinstructor() public constant returns(string){
return(fhash);
}
function setinstructors(string _comphash) public {
comphash = _comphash;
emit Instructors(_comphash);
}
function getinstructors() public constant returns(string){
return(comphash);
}
function compareStrings() public view returns (bool){
return sha256(fhash) == sha256(comphash)? true : false;
}
}
Image of Mist response
Related
I am a newbie studying Uniswap V3's github code. I came up with noDelegateCall.sol and I found out the way to prevent a contract to be delegatecalled from another cotract. As I tried to implement this, I caught up with the problem.
pragma solidity >0.8.0;
contract Receiver {
string greeting = "Hello";
address private immutable original;
event Greeting(string greeting, address original, address addressThis);
constructor() {
original = address(this);
}
function checkNotDelegateCall() private view {
require(address(this) == original);
}
modifier noDelegateCall() {
checkNotDelegateCall();
_;
}
function greet() external noDelegateCall {
emit Greeting(greeting, original, address(this));
}
}
contract Sender {
string greeting = "Hi";
function delegatedGreeting(address _contract) external {
(bool success,) = _contract.delegatecall(
abi.encodeWithSignature("greet()")
);
}
}
If I call function delegatedGreeting, I expect the function to be reverted because variables original and address(this) differs. However, although it emits an empty event, it still doesn't reverts. Why does this happen?
When the low-level delegatecall reverts, it doesn't automatically revert the main transaction. Instead, it returns false as the first return value of the delegatecall() function.
So you need to check the return value (in your case bool success) and validate that.
function delegatedGreeting(address _contract) external {
(bool success,) = _contract.delegatecall(
abi.encodeWithSignature("greet()")
);
require(success == true, "delegatecall failed");
}
I am trying to return a value using a function of a deployed smart contract on the blockchain.
pragma solidity 0.6.2;
contract Caller {
address cont;
function changeAdd(address _change) public {
cont = _change;
}
function caller (bytes memory test) public returns(bool, bytes memory) {
bytes memory payload = abi.encodeWithSignature("callMe(bytes)", test);
(bool success, bytes memory result)= address(cont).call(payload);
return (success, (result));
}
function viewCont() public view returns(address) {
return cont;
}
}
And the deployed test contract is this:
pragma solidity 0.6.2;
contract Store {
uint counter;
function callMe(bytes calldata test) external returns(bytes memory) {
counter++;
return abi.encode(test);
}
function viewCounter () public view returns(uint256) {
return(counter);
}
function clearCounter() public {
counter = 0 ;
}
}
In this example, I am deploying contract "Store" on the blockchain where it is assigned a random address, which can be pointed at via the Caller.changeAdd function in order to use Caller.caller function. Thus, I am trying to send data in the form of bytes to the Store contract, which is supposed to send back the same data to the Caller contract. I am trying to isolate -only- the data that is originally sent, so I can use it to test interaction between smart contracts on the blockchain. I tried in the beginning to send an integer, but I couldn't find a way to do it. So I used bytes and it worked, but still the data I receive isn't the same that I send in the first place(e.g. I send 0x0 and I receive a big bytes number, which isn't the same as 0x0).
I could appreciate any help on how to receive and handle data between two different, unlinked smart contracts, thank you in advance.
Do you try to use abi.decode function of Solidity.
In the below example, contract B calls setName of contract A, then decodes the result by using abi.decode function.
contract A {
string public name;
constructor(string memory tokenName) public {
name = tokenName;
}
function setName(string memory newName) public returns ( string memory){
name = newName;
return newName;
}
}
contract B {
event Log(string msg);
string public myName;
function call(address addr, string memory newName) public {
bytes memory payload = abi.encodeWithSignature("setName(string)", newName);
(bool success, bytes memory result)= addr.call(payload);
// Decode data
string memory name = abi.decode(result, (string));
myName = name;
emit Log(name);
}
}
In this solidity code the finalizeRequest() is giving a run-time error.
Here is the error :
Campaign.finalizeRequest(uint256) 0x692...77b3a
transact to Campaign.finalizeRequest errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information.
Here is the code:
pragma solidity ^0.4.17;
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool complete;
uint approvalCount;
mapping (address => bool) approvals;
}
address public manager;
uint public minimumContribution;
// address[] public approvers;
mapping (address => bool) public approvers;
Request[] public requests;
uint public approversCount;
function Campaign(uint minimum) public {
manager=msg.sender;
minimumContribution=minimum;
}
function contribute() public payable {
require(msg.value>minimumContribution);
// approvers.push(msg.sender);
approvers[msg.sender]=true;
approversCount++;
}
function createRequest(string description,uint value,address recipient) public restricted {
// require (approvers[msg.sender]);
Request memory newRequest=Request({description:description,value:value,recipient:recipient,complete:false,approvalCount:0});
requests.push(newRequest);
}
function approveRequest(uint index) public {
Request storage request=requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender]=true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount>=(approversCount/2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete=true;
}
modifier restricted() {
require (msg.sender == manager);
_;
}
}
As far as I could debug, when I comment out request.recipient.transfer(request.value); in the finalizeRequest() function no runtime error is thrown. So error seems to be in this line of code.
As far as i see your finalizeRequest() function consists transfer of ether as defined request.recipient.transfer(request.value); so you need to make your finalizeRequest() as payable.
replace finalizeRequest() with:
function finalizeRequest(uint index) public restricted payable {
Request storage request = requests[index];
require(request.approvalCount>=(approversCount/2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete=true;
}
Thumb Rule: Whenever you are sending or receiving ether in any function, mark it as payable.
Reason why you need payable keyword is well explained here.
I want to get the value that is inside of struct in Solidity,
but I have no idea how to get it.
pragma solidity >=0.4.21 <0.6.0;
contract PlaceList {
struct hoge {
uint id;
address user;
}
hoge[] public hoges;
constructor() public {
admin = msg.sender;
}
function set(uint id) public {
hoges.push(hoge(id, msg.sender));
}
function getId() public view returns(uint) {
return (hoges[0].id);
}
}
When I call getId, console command say this,
ƒ () {
if (abiItemModel.isOfType('constructor')) {
return target.executeMethod(abiItemModel, arguments, 'contract-deployment');
}
return targe…
Could you give me any advise how to get id by using solidity function, please?
hoges[0][0] will work as it points to the first element, 'id' .
I deployed two contracts, one is Callee and the other is Caller. Caller consumes functions provided by Callee. Function call directly to Callee is success, however, Caller does NOT work. Actually, I'v tried different cases from internet, none of them works. Do I miss some tricky things? Below is source code:
Callee.sol
pragma solidity ^0.4.6;
contract Callee {
uint[] public values;
function getValue(uint initial) public pure returns(uint) {
return initial + 150;
}
function storeValue(uint value) public {
values.push(value);
}
function getValues() public view returns(uint) {
return values.length;
}
}
Caller.sol
pragma solidity ^0.4.6;
contract Caller {
function someAction(address addr) public returns(uint) {
Callee c = Callee(addr);
return c.getValue(100);
}
function storeAction(address addr) public returns(uint) {
Callee c = Callee(addr);
c.storeValue(100);
return c.getValues();
}
function someUnsafeAction(address addr) public returns(bool){
return addr.call(bytes4(keccak256("storeValue(uint256)")), 100);
}
}
contract Callee {
function getValue(uint initialValue) public returns(uint);
function storeValue(uint value) public;
function getValues() public returns(uint);
}
Caller is technically working, but not doing what you're expecting.
The problem is that Caller.someAction is not marked with the pure or view modifiers, so your function call is triggering a new transaction. Transaction calls can't return values (it compiles and runs, but nothing is returned).
If you change Caller.someAction to be a pure function (and, also change Callee.getValue in the interface to be pure as well to match the contract), you will get the expected 250 returned.
pragma solidity ^0.4.6;
contract Caller {
function someAction(address addr) public pure returns(uint) {
Callee c = Callee(addr);
return c.getValue(100);
}
function storeAction(address addr) public returns(uint) {
Callee c = Callee(addr);
c.storeValue(100);
return c.getValues();
}
function someUnsafeAction(address addr) public returns(bool){
return addr.call(bytes4(keccak256("storeValue(uint256)")), 100);
}
}
contract Callee {
function getValue(uint initialValue) public pure returns(uint);
function storeValue(uint value) public;
function getValues() public returns(uint);
}
In terminal:
$ truffle migrate --reset
Compiling .\contracts\Callee.sol...
Compiling .\contracts\SimpleContract.sol...
Writing artifacts to .\build\contracts
Using network 'development'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0x58a14c93acc733bb08e4bb56978d0bb466f8aca7659673426d989ee7e0e626f3
Migrations: 0x69ed5e4d6172639ed7d3c456ea8b2f2562c7dbcd
Saving successful migration to network...
... 0x9a3831076748cc6179ef3e4b3e466c3a4a871e196376bc22c984e91e95fdc567
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing Caller...
... 0x7be6840c86a356decacc13967d50ef4fea30e86d30d69b19fb9998ce500c95e8
Caller: 0xb8c5e079af71813acac73bff9ca8e9e068660e86
Replacing Callee...
... 0xba7f588f9119e67968a7d6ab0110d79e1ecd3003e10cce3134018d42e966c8be
Callee: 0xd5c110c2f6566fd56749ec1a11328405f9935385
Saving successful migration to network...
... 0xc1526876e365189be1529a0943042e3a25e395a5cc19930ad907a694165104f1
Saving artifacts...
$ truffle console
truffle(development)> var caller = Caller.at('0xb8c5e079af71813acac73bff9ca8e9e068660e86');
undefined
truffle(development)> caller.someAction('0xd5c110c2f6566fd56749ec1a11328405f9935385');
{ [String: '250'] s: 1, e: 2, c: [ 250 ] }