I'm having a problem with the blockhash function at remix.ethereum.org.
Despite several attempts with different codes the blockhash function always causes problems and the result is that all variables are returned with a value of zero.
In the case below, the _previousBlockNumber variable always return zeroed.
If the blockhash function line is commented out then the error does not occur and at least the _previousBlockNumber variable returns correctly.
I've tried several different versions of compilers.
pragma solidity ^0.5.5;
contract Test {
constructor() public {
}
function rand() public view returns(uint,bytes32) {
uint _previousBlockNumber;
bytes32 _previousBlockHash;
_previousBlockNumber = uint(block.number - 1);
bytes32 _previousBlockHash = bytes32(blockhash(_previousBlockNumber));
return (_previousBlockNumber,_previousBlockHash);
}
}
It's a bug issue?
Thanks for any help.
I tried to run this code to fix the problem and it's working for me with some changes. Same contract you can find on Rinkebey Testnet with this address 0x86ee6d633fd691e77dc79cbdb2a9fb108f79ecbd.
pragma solidity ^0.5.5;
contract Test {
uint256 i;
constructor() public {
}
function rand() public view returns(uint,bytes32) {
uint _previousBlockNumber;
bytes32 _previousBlockHash;
_previousBlockNumber = uint(block.number - 1);
_previousBlockHash = bytes32(blockhash(_previousBlockNumber));
return (_previousBlockNumber,_previousBlockHash);
}
function setI(uint256 k) public{
i = k;
}
}
Initially, you were declaring the _previousBlockHash two times, and second time on the line of blockhash function. I fix it and working fine.
Secondly, in the current contract code you are not changing any state of the contract and not doing any transaction, rand() is just an call, which will not add any other block. So it will always remain 0. I add one dummy transaction function for testing which is working fine now.
Lastly, try to run this on live test network to see actual things.
Hope it will work.
Related
I got stucked in thoughts guys and I need bit of clarification to move it forward.
(Description is about real problem, code is for best (I hope so..) understanding me)
I have main contract A that uses erc20 token and its transfer functions, there is also inherited Ownable and whitelist with accessing addresses of contracts e.g. B,
I passing A address to the B constructor
I created instance of A in B (because in B I calculate collateral and I want to split to two different contracts)
Protecting A using Ownable it's enough from accessing A from 3rd party while interacting with A from A, Ownable in B isnt work because can't use right msg.sender, without modifiers someone can create instance of B in his contract and have access to my A, isn't it?
Thanks in advance
EDIT: I change a code for more to understand
// SPDX-License-Identifier: MIT
pragma solidity 0.8;
contract Ownable {
mapping (address => bool) private whiteListed;
modifier onlyWhiteListed {
require(whiteListed[msg.sender] == true, "You're not whitelisted");
_;
}
constructor () {
whiteListed[msg.sender] = true;
}
function setWhiteListed(address addr, bool trueOrFalse) public onlyWhiteListed {
whiteListed[addr] = trueOrFalse;
}
function getWhiteListed(address addr) public view returns (bool) {
return whiteListed[addr];
}
}
contract A is Ownable {
B public b;
event LogMsgSender(address who);
constructor() {
b = new B(address(this));
//setWhiteListed(address(this),true);
setWhiteListed(address(b),true);
}
function callMe() public onlyWhiteListed { // here I can only get real caller msg.sender
emit LogMsgSender(msg.sender); // when interact with that contract, not outside of contract
}
function callSender(address sender) public onlyWhiteListed { // here I can get real caller msg.sender from other contract
emit LogMsgSender(sender); // but is it worth to passing addresses ?
} // and HERE is my question: is this aproach secure??
}
contract B is Ownable {
A public a;
constructor(address addr) { //in remix I can't deploy in one time while
a = A(addr); //deploying A, I have to deploy copying addresses of A and do it separately
} //and after deploying also setWhiteListed() to whiteList in A
function callMe() public onlyWhiteListed { // this call isn't good for interact with sender, it's exlusive for calling as contract B
a.callMe(); // copies of this contract can
}
function callSender() public onlyWhiteListed { // modifiers protect from 3rd party contracts but
a.callSender(msg.sender); // that way it only can be used by deployer and whitelisted, (without modifiers they aren't secure)
} // bad idea ofc is adding to whitelist all over and over and
// it's impossible to recognize which to add which not
}
contract C {
B public b;
constructor(address addr) {
b = B(addr);
}
function callMe() public { //when modifiers is added this contract can't call these functions
b.callMe(); // but with modifiers functions can't be used to get right sender address
}
function callSender() public {
b.callSender();
}
}
So now I'm deciding to inherite e.g. B is A and I simply get right sender, what do you think?
You've got a lot of syntax/logic errors in the code you posted. Not only are you missing onlyOwner modifiers, but your calls in B are via the type A: A.receiveToken() is not the same as a.receiveToken() ... so you've probably made several typos in posting your question (Should say a=A(aAddr); in the constructor etc).
The msg.sender will be "b" when b calls a.sendToken() but tx.origin will be unchanged. Checking msg.sender checks which contract called you. In other words, it is checking (inside onlyOwner of A.sendToken) whether b is the one that called a.sendToken().
Start by fixing all the errors and then insert some debug logging for yourself, so you can see how msg.sender is changing during the calls. You can also log tx.origin to see how that remains the original sender.
The point is that the owner of the A that B created is that particular instance of B (b). It's therefore "natural" that inside B, it can call a.whatever() as a's owner.
You didn't specify, but if you are using the Ownable contract from openzeppelin you need to pass the modifier onlyOwner for the methods that you want to be protected. Ex:
function sendToken(uint value) public onlyOwner {
//transferFrom
emit Sent(value);
}
Do you know if is it possible to call the function of an other contract in Solidity used in Substrate based chain and compiled with solang ? At first glance it seems impossible but I doubt it.
As a basic example I'm trying to get a "incrementor" working only if a "flipper" is on:
contract Flipper {
bool private value;
constructor (bool initValue) {
value = initValue;
}
function flip () public {
value = !value;
}
function get () public view returns (bool) {
return value;
}
}
I want to use a Flipper instance in my Incrementor contract to allow / disallow incrementing.
import "flipper.sol";
contract Incrementor {
uint256 _count;
Flipper _flipper;
constructor (uint256 _initialValue, Flipper _flipperContract) {
_count = _initialValue;
_flipper = _flipperContract;
}
// --
// Mutators
// --
function increment () public {
require(_flipper.get(), "Flipper must be ON");
_count += 1;
}
function superFlip () public {
_flipper.flip();
}
function setValue (uint256 v) public {
_count = v;
}
// --
// Accessors
// --
function count () public view returns (uint256) {
return _count;
}
}
When testing all of this on polkadotjs; I have a negative answer saying contract trapped ALONG with a success message (but the totality doesn't work).
(Failure on the "increment" message):
I'm not sure but I suspect this problem to arise from the difference in addressing in the EVM vs WASM.
In the article linked bellow, we can see how an external contract function is "manually" invoked with an "address.call(bytes4(keccack25('...')), args)".
https://medium.com/#blockchain101/calling-the-function-of-another-contract-in-solidity-f9edfa921f4c
Except this is working in a EVM environment; not a WASM substrate environment.
Can someone help ?
This is my second day in Solidity and I have no clue what's wrong with this code here. (I have never done any coding except some newbie level C and HTML in high school) so any help is appreciated!
pragma solidity ^0.6.0;
contract SimpleStorage {
//this will get initialized as zero
uint256 public favoritNumber;
function store(uint256 _favoritNumber) public {
favoritNumber = _favoritNumber;
}
function retrieve() public view returns(unit256) {
return favoritNumber;
}
}
The error is caused by a typo.
Change the unit256 to uint256 (unsigned integer).
I try to compile a smart contract using Truffle framework and I get following output:
Compiling ./contracts/PartProduction.sol...
InternalCompilerError: Stack too deep, try using fewer variables.
Compilation failed. See above.
Truffle v5.0.1 (core: 5.0.1)
Node v11.6.0
The source code of the smart contract written with Solidity 0.5.0 is:
pragma solidity 0.5.0;
contract PartProduction {
enum State {
productionRequested,
parametersObtained,
manufacturerObtained,
productionForwardedToManufacturer,
printing,
printed,
postProcessing,
postProcessed,
qualityChecking,
qualityChecked,
productionFinished
}
enum Priority {
low,
normal,
high
}
struct Company {
address vehicleEthAddress;
address myWebService;
}
struct Manufacturer {
string id;
string location;
address productionMachine1;
address productionMachine2;
address productionMachine3;
}
struct Production {
string productionParameters;
string designParameters;
State state;
Priority priority;
string partNumber;
uint256 cost;
uint256 productionForwardedTime;
uint256 productionStartTime;
uint256 productionEndTime;
address partID;
string myIdentifier;
string location;
}
Company public company;
Manufacturer public manufacturer;
Production public production;
constructor(
address _vehicleEthAddress,
string memory _myIdentifier,
string memory _vehicleLocation,
string memory _partNumber,
Priority _priority)internal {
company.myWebService = msg.sender;
company.vehicleEthAddress = _vehicleEthAddress;
production.partID = address(this);
production.state = State.productionRequested;
production.partNumber = _partNumber;
production.priority = _priority;
production.myIdentifier = _myIdentifier;
production.location = _vehicleLocation;
}
function setParameters(string calldata _designParametersHash, string calldata _productionParametersHash) external {
require(msg.sender == company.myWebService);
require(production.state == State.productionRequested);
production.designParameters = _designParametersHash;
production.productionParameters = _productionParametersHash;
production.state = State.parametersObtained;
}
function setManufacturer(string calldata _manufacturerId, string calldata _manufacturerLocation) external {
require(msg.sender == company.myWebService);
require(production.state == State.parametersObtained);
manufacturer.id = _manufacturerId;
manufacturer.location = _manufacturerLocation;
production.state = State.manufacturerObtained;
}
function forwardProductionData(uint256 _productionForwardedTime) external {
require(msg.sender == company.myWebService);
require(production.state == State.manufacturerObtained);
production.state = State.manufacturerObtained;
production.productionForwardedTime = _productionForwardedTime;
}
function registerproductionMachine1(address _productionMachine1) external {
require(msg.sender == company.myWebService);
manufacturer.productionMachine1 = _productionMachine1;
}
}
I would like to know if there is a way to understand and identify the part where the number of variables exceeds. Should I turn everything into a mapping? The compiler does not provide me with further information.
Also, I found this question, it's similar, but I'm not sure it's the same problem, a cons it is to save the variables in memory (memory keyword) when you do a get, another is to set them. Is the use of mapping the only possible alternative to tackle this problem? Furthermore, the smart contract is not concluded, many other parts will be added later.
As far as I can see, your stack is too deep for the struct production, you can use a trick here to solve this issue, create a separate smart contract with the name Production, define the structure there and import the contract in this smart contract. This will help you in both reducing your gas consumption while deploying the contract and this stack too deep issue.
This you can do for other structs as well if you wish. The only thing you need to take care of is the mapping while you implement for mapping the structure to a particular contract. As for each contact it will be counted as separate map.
Let me know if you need any further assistance. I want you to try out this solution hopefully, this will work.
For this project, I am coding smart contracts for Ethereum using Solidity.
In the following code, the variable numCertificates should initially be 1. Nonetheless, newCertificateId is 0 when assigned. According to the debugger (I'm using remix.ethereum.org), for some reason, numCertificates becomes 0 as soon as the line where newCertificateId is assigned is reached.
I have played around with remix a lot, and according to it, numCertificates is 1 until exactly the aforementioned line is reached. Also, I think that if I modify numCertificates in another function, the variable stays the same as before.
My attempts at trying to figure this out lead me to believe that when I access numCertificates, I am not accessing the public state variable but something else.
Why does this code have this problem and how can it be solved?
pragma solidity ^0.4.21;
contract MyToken {
// ... lots of irrelevant stuff here
mapping (uint64 => Certificate) public certificates;
uint64 numCertificates = 1;
// ... lots of irrelevant stuff here
function MyToken() public {
// ... likely irrelevant code
}
function produceCertificate(
// ... likely irrelevant parameters
) public {
// Create the certificate in memory
numCertificates;// only for debbuging
Certificate storage newCertificate = constructCertificate(meterId, timestamp, carbonMitigationValue, owner);
uint64 newCertificateId = numCertificates;
newCertificate.certificateId = newCertificateId;
// Save the certificate
certificates[newCertificateId] = newCertificate;
numCertificates++;
}
function constructCertificate(
uint64 meterId,
uint32 timestamp,
uint48 value,
address owner
) internal returns (Certificate storage newCertificate) {
newCertificate.meterId = meterId;
newCertificate.timestamp = timestamp;
newCertificate.value = value;
newCertificate.owners.push(owner);
newCertificate.ownershipSplit[owner] = value;
newCertificate.burned = false; // by default new certificates are fresh
return newCertificate;
}
}