I'm having problems setting a value in a deployed BSC smart contract, below is the problematic solidity function, is the fact '_value' has been used not 'value' as the pass parameter ?
function setSwapTokensAtAmount(uint256 _value) external onlyOwner
{
swapTokensAtAmount = _value;
}
I have looked at other contracts and can't see any that use the '_' when labelling a pass parameter value, which can be used (from my understanding) denote a public or private variable.
It's a common practice to name function-scoped variables starting with underscore. But naming the variable with or without underscore doesn't have any effect on the resulting functionality.
I see that your function uses the onlyOwner modifier. While your code doesn't show the modifier implementation, we can assume that it controls that only authorized sender can execute the function.
So a very likely reason why you cannot update the variable is that you're trying to execute the function from a different address than the authorized owner.
Related
I was wondering what information are publicly visible and intelligible when an EOA (external ownable address) calls a payable function on a smart contract, with some parameters and a return value.
Let us say I have the smart contract function below, the question is: 'is the return value visible somewhere on the blockchain?'. I am using Solidity 0.8.12.
function askForSecretCode(uint time) external payable returns (bytes32) {
require(msg.value == 42, 'Need to pay 42 wei.');
secretCodes[secretCodesNum] = keccak256(abi.encodePacked(msg.sender, time);
return keccak256(abi.encodePacked(msg.sender, time);
}
Anyone can see the input time param value as a part of a transaction invoking the askForSecretCode function.
Even though if you don't publish the contract source code, the bytecode is public, and there are decompilers that can (with some error rate) help generate source code back from the bytecode. So let's assume that the source code is available as well.
From the source code (or usually even from the pseudocode generated by the decompiler), anyone can determine the storage slot of secretCodesNum (which from the context seems to be a property of the contract) and retrieve its value using the eth_getStorageAt RPC method, including historical values.
Using these secretCodesNum values, they can use the same method to determine storage slots of any secretCodes[secretCodesNum] and their values.
TLDR: Never ever store private data on the blockchain.
Where in the code and what is the proper way to add legal verbiage to my ERC20 Smart Contract?
I've seen a few samples where it gets saved on a variable and then that variable value is referenced in the body of a function using memory.
i.e.
contract MyToken is ERC20, Ownable {
string public processNumber = "0041518-41.1982.8.26.0053";
string public legalBinding = "a lot, a lot of verbiage would go here";
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, 9000000 * 10 ** decimals());
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
function setProcessNumber (string memory v) public onlyOwner() {
processNumber = v;
}
function setLegalBinding (string memory v) public onlyOwner() {
legalBinding = v;
}
}
What are those two last functions doing anyway does it ever get executed or just saved in memory?
Is that the correct practice?
Is there a better approach to this?
Where in the code do developers typically add that type of info?
If I'm to save a massive string of text containing all the legal verbiage. on a variable can I save those on a template literal using back-ticks to leverage multiple lines breaks inside the string and so forth?
I would like to go point-by-point to your question :
What are those two last functions doing anyway does it ever get executed or just saved in memory?
These functions are basically overriding the values of these variables, which in your case, are by default initialised at the very beginning of the contract. As we have the onlyOwner() modifier set on these functions, only the owner can change these variables by calling these methods explicitly, and by providing the necessary Gas cost.
Is that the correct practice? Kind-of, Yes
Is there a better approach to this?
The method can be modified to view restriction
Where in the code do developers typically add that type of info?
If you want the value to be a constant, i.e, it should not be changed through out the course of the contract, add the constant modifier. Additionally, you can add make the variable immutable, which means the initial constant value string can be avoided, and the variable can only be initialised with a constant value at first run, and then the value cannot be changed.
If I'm to save a massive string of text containing all the legal verbiage. on a variable can I save those on a template literal using back-ticks to leverage multiple lines breaks inside the string and so forth?
Yes, you can. Please refer here : https://docs.soliditylang.org/en/v0.8.0/internals/layout_in_storage.html?highlight=string
Hope that it helps!
My understanding is that you can define an operator when instantiating a custom ERC-777, that can make transfers without needing to be approved by the senders using the operatorSend function. However, can't seem to get the address of the contract that deploys the token into the inherited constructor. I tried pushing the address into the array in the body of the constructor, but that doesn't seem to take.
contract MainToken is ERC777 {
address[] ops=;
constructor () ERC777("MYTOKEN", "MTK",ops) {
ops.push(msg.sender);
}
...
}
If I try putting it directly into the constructor like so ERC777("MYTOKEN", "MTK",[msg.sender]), I get
Invalid type for argument in modifier invocation. Invalid implicit
conversion from address[1] memory to address[] memory requested.
Solidity currently doesn't allow defining a dynamic-size array in one expression. Note: [msg.sender] from your example is a fixed-size array definition.
Also, your approach with defining the ops property doesn't work, because of the order how EVM processes the constructor.
Storing child (MainToken) constructor arguments to memory (in your case no arguments)
Executing parent constructor.
In your case the execution of ERC777("MYTOKEN", "MTK", ops) fails, because the storage variable ops is not available yet.
Executing child constructor (in your case ops.push(msg.sender);)
So the easiest Solution I could come up with, is passing the address from the MyToken argument. This is useful if you have control over the deployment process and can manually pass the value of msg.sender when you're deploying the contract.
pragma solidity 0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC777/ERC777.sol';
contract MyToken is ERC777 {
constructor(address[] memory defaultOperators)
ERC777('MYTOKEN', 'MTK', defaultOperators) {
}
}
If you're not going to have control over the deployment and need to assign msg.sender in constructor, I suggest copying the ERC777 contract locally and modifying its constructor, so that it only adds the msg.sender.
I came across this Solidity code:
tx.destination.call.value(tx.value)(tx.data)
but don't understand how it works... especially the tx.data at the end.
This statement is calling a function represented by tx.data on the address at tx.destination passing in wei (tx.value).
To break it down further:
tx.destination is an address. An address has built in members and functions, including call which allows you to execute functions on a contract without the ABI (see Address type definition). For example, you can call a method foobar on a contract without a defined interface like this:
contractAddress.call(bytes4(keccak256("foobar(uint256,uint256)")), val1, val2); // where val1 and val2 are the uint256 parameters to pass in
Using call alone will use some default values when calling the other contract's method. For example, all of the remaining gas will be forwarded. If you want to change those values, you can adjust it by supplying your own gas and/or wei values, which looks like a function call itself:
contractAddress.call.value(9999999)();
This will send 9999999 wei to contractAddress. You can override both the gas and ether sent by chaining multiple function calls:
contractAddress.call.value(99999999).gas(77777)();
The last set of parens in both examples indicate to use the fallback function when sending the wei. You can see a similar example in the Solidity docs FAQ.
If you wanted to call something other than the fallback function, you would combine the 2 examples above, which is what the code you posted is doing. The fact that they are using tx is a bit confusing since that is normally a built-in reference, but they are likely shadowing that and it's referencing a struct with destination, value, and data members.
Newbie.
There is a go-ethereum method:
eth.estimateGas({from:'firstAccount', to:'secondAccount'})
that works well,
but same method with contract address like:
eth.estimateGas({from:'firstAccount', to:'contractAddr'})
fails with error
gas required exceeds allowance or always failing transaction
I have looked into go-ethereum source code and it has the line, that contains proposal to use contract address as second parameter:
https://github.com/ethereum/go-ethereum/blob/master/accounts/abi/bind/base.go#L221
The question is: is there any possibily to use eth.estimateGas with contract address as second parameter and how to avoid above error?
Thank you.
You're not specifying what you're executing in the contract, so there's nothing to estimate. When you estimateGas for a transfer to an EOA account, there is no contract code to execute, so there is no message data to be sent as part of the transaction object. If you're estimating gas on a contract call, you need to include the data for the contract.
For example, if you want to estimate gas to setValue(2) method in this contract
pragma solidity ^0.4.19;
contract SimpleContract {
uint256 _value;
function setValue(uint256 value) public {
_value = value;
}
}
your call would be
var data = '552410770000000000000000000000000000000000000000000000000000000000000002';
eth.estimateGas({from: fromAccount, to: contractAddress, data});
The value for data comes from encoding the function signature and the parameter value(s). You can use a simple tool (like https://abi.hashex.org) to generate this. You just enter the function name along with the parameter argument types and their values, and it will generate the message data for you. You can also do this using web3js.
EDIT - I neglected to consider contracts with fallback functions. Executing estimateGas on a contract without passing in message data provide the estimate for contracts that have a fallback function. If the contract does not have a fallback function, the call will fail.