I'm traing to get data from an off-chain API to use it in my smart contract. For this, I'm using Chainlink oracle.
I've seen jobs to get one Uint256 or one Bool or a Bytes32 variable. But what if you want to receive an array?
I want to receive something like [1, 2, 3, 4] as an uint[] to be able to loop and use the individual values.
What's the best way to do this?
I already used the Get->Bytes32 and the Get->Bytes, method but then I need to parse these bytes inside the EVM and I don't think that's a good idea.
At the moment arrays are not supported as a response type, here is the list of currently supported response types.
You can:
Read uint256 value by uint256 value, assuming it's a fixed-size array, like this
Make a Multi-Varibale Responses request
Make a Large Responses request, which you mentioned, and handle those bytes32 values. Keep in mind that, currently, any return value must fit within 32 bytes. If the value is bigger than that, make multiple requests.
Related
I am building a scraper to get all Swap data from Uniswap using web3js.
So far I subscribe to the log and filter topics by Swap() event.
then I decode the data and get amount0In, amount1In, amount0Out, amount1Out.
My problem is in the swapExactETHForTokensSupportingFeeOnTransferTokens() function.
Normally a swap has token0 in and token1 out, but this function gives me values for 3 of the 4 and I can not seem to understand how to handle that. eventually what I want is to know what they spend, what they got and what I need to update the new reserves of that pair.
If someone has the understanding of the Uniswap RouterV2 contract swap functions, I would like to get some pointers on how to handle the data to get my calculations right.
I found the solution here ethereum.stackexchange Anyone with the same question gets a very detailed answer there.
some contracts actually transfers to recipient specified amount of tokens minus 10% (5% tax fee and 5% liquidity fee) 208940457743532637 - 10% = 188046411969179375 and emits Transfer event. Then, PancakePair _swap function emits Swap event with base value of Amount0Out 208940457743532637
Amount0In is greater than zero because the token contract returns part of tokens as a liquidity pair on Pancake Swap.
I am wondering besides these below mathematical expressions are there any other functions available to call inside a smart contract? Like math functions, like pi, sin, cosine, random() etc?
I am wondering if one can write smart contracts that require a little more than just basic arithmetic.
Below Image is taken from this page:
https://docs.soliditylang.org/en/develop/cheatsheet.html#function-visibility-specifiers
Solidity doesn't natively support storing floating point numbers both in storage and memory, probably because the EVM (Ethereum Virtual Machine; underlying layer) doesn't support it.
It allows working with them to some extent such as uint two = 3 / 1.5;.
So most floating point operations are usually done by defining a uint256 (256bit unsigned integer) number and another number defining the decimal length.
For example token contracts generally use 18 decimal places:
uint8 decimals = 18;
uint256 one = 1000000000000000000;
uint256 half = 500000000000000000;
There are some third-party libraries for calculating trigonometric functions (link), working with date time (link) and other use cases, but the native language currently doesn't support many of these features.
As for generating random numbers: No native function, but you can calculate a modulo of some pseudo-random variables such as block.hash and block.timestamp. Mind that these values can be (to some extent) manipulated by a miner publishing the currently mined block.
It's not recommended to use them in apps that work with money (pretty much most of smart contracts), because if the incentive is big enough, there can be a dishonest miner who can use the advantage of knowing the values before rest of the network and being able to modify them to some extent to their own benefit.
Example:
// a dishonest miner can publish a block with such params,
// that will result in the condition being true
// and their own tx to be the first one in the block that executes this function
function win10ETH() external {
if (uint256(blockhash(block.number)) % 12345 == 0) {
payable(msg.sender).transfer(10 ether);
}
}
If you need a random number that is not determinable by a miner, you can use the oracle approach, where an external app (called oracle) listens to transactions in a predefined format (generally also from&to specific addresses), performs an off-chain action (such as generating a random number, retrieving a google search result, or basically anything) and afterwards sends another transaction to your contract, containing the result of the off-chain action.
I have a function that needs to send tokens to a lot of accounts.
I know that a write operation into a store is very costly.
I have read when doing computing on storage it's better to do it on a memory variable and then set this memory variable into the storage and by that save the write operation on storage.
so what I was thinking to do is something like this
mapping (address => uint256) private _balances;
function addToBalance(address[] memory accounts,uint[] memory amounts) public{
mapping (address => uint256) memory balances = _balances;
for(uint i=0;i<accounts.length;i++){
balances[accounts[i]]+=amounts[i];
}
_balances = balances;
}
the _balances mapping can become pretty big. so is it really a better way to reduce the costs?
Not with a mapping.
Mapping (and dynamic-size array) values are all "scattered" in different storage slots. The slot positions are determinable, but because they are calculated based on a hash, the value for key 1 can be in storage slot 123456789 and the value for key 2 can be in storage slot 5. (The numbers are made up just to show an easy example.)
Which means, when you're saving N values into a mapping (under N keys), you always need to write into (the same amount) N storage slots. Writing into one (256bit) slot costs 5,000 gas, and it can add up quickly.
So apart from moving the values into a fixed-size array (which doesn't make much sense in this use case when you're storing balances of an unknown amount of addresses), I'd consider shifting the transaction costs to your users (have a list of eligible users and another list of already used airdrops and let them claim it themselves).
Solidity allows mapping types inside a struct. How many bytes does such a field cost?
Specifically I'd like to optimise the storage layout of the following type.
struct Balance {
uint40 amount;
mapping(address => uint) allowances;
}
I think you mean the storage layout, not memory layout.
uint is an alias for uint256, which is 256-bits. So each value stored in that mapping uses one 32-byte slot in storage.
EDIT
For the full Balance struct, each one will consume two slots in storage, but one slot will always be zero. The first slot is consumed by the uint40, and the second is a placeholder for the mapping that doesn't actually have any value stored. In terms of gas cost, that's free.
So storing a new Balance will write one 32-byte word to storage, and then each uint you add to the allowances mapping will write one 32-byte word to storage.
I have seen some transactions in etherscan.io.But I have found that even invoking the same function in the same smart contract, the gas used by txn are different.I try to found that maybe the input data result in it.Really?
The input data might be different, but also the state stored in the smart contract might be different (and change e.g. the number of times a loop iterates). Also, if storing nonzero data in a state variable that previously held zero data, or vice versa, will change the gas usage. For example, a simple function that toggles a boolean variable will not use the same amount of gas on any two consecutive calls.
Check out https://ethereum.stackexchange.com/ for future questions like this!
Each time you invoke a function in contract that requires state change in the block,it would cost x amount of gas , so every time you call different or same function in a contract that requires a state change,you would see that x amount of gas is being deducted along with its taxation Id.This is the reason you see different Txn on same function.
More about Gas and Transaction in the link below. http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html