currently, I'm practicing solidity. However, I'm a little confused about accessing a private variable in a contract.
For example here;
address private a;
address private b;
mapping (bytes32 => uint) public people;
mapping (bytes32 => mapping(address => uint)) public listOfEmp;
bytes32[] public list;
bytes32 private z;
I can access 'a' with
web3.eth.getStorageAt("0x501...", 0)
How can I access 'z' here? From a different contract.
Thank you
You can access the storage of your contract even if it's private.
Try this:
web3.eth.getStorageAt("0x501...", 5)
If you want to access the map or array, check this document for layout of state variables: https://solidity.readthedocs.io/en/v0.4.24/miscellaneous.html
By the way, you should always use getProof to validate the value.
Think of Ethereum as a process running on your machine or remotely. Using web3.eth.getStorageAt you read data from the process memory. In the same way you can read the data of every program on your computer.
On other hands, high level programming languages like Java, C++ or Solidity frequently define access rules on variables and functions (private, protected, etc). But these rules only hold in the context of the program execution. For Solidity that context is the execution of transaction.
It means that the private field is private only for other contracts trying to read it. But can be read by external (and pretty low-level) API's like web3.eth.getStorageAt.
With web3.eth.getStorageAt you can read the complete storage of any contract externally (off-chain). But I want to make it clear - it is not as simple, as the 1. variable at position 0 (the a in your example), and the 6. variable at position 5 (the z in your example).
getStorageAt returns a storage slot, which is 32 bytes. And to read the variables data, you indeed have to know the order in which the variables are declared in a contract, but also you need to know the data types. As the variables of the fixed size could be stored in a single storage slot if they occupy <= 32 bytes.
For example, if your contract would be:
address private a;
bool private b;
Reading the first slot web3.eth.getStorageAt("0x501...", 0) would return not just the address a but also the value for b.
The address requires 20 bytes. The bool: 1 byte. That is why the second variable is not stored at the second slot, but is placed into the first one, as the first slot has enough storage space left: 32bytes - sizeof(address) = 12bytes.
This means, you need to know the slot number for a variable, but also the size and offset.
address private a; // slot 0, size 20, offset 0
bool private b; // slot 0, size 1, offset 20
Things get more complicated with arrays, mappings, string and dynamically sized types.
For example, for arrays:
Fixed length: each item as a single variable:
// slot 0 for item0
// slot 1 for item1
// slot 2 for item2
address[3] private a;
// slot 3
address private b;
Dynamic length:
// slot 0 for current array length
// each item at specific index is accessed under the slot: keccak256(encodePacked(0)) + index
address[] private a;
// slot 1
address private b;
Multiple slots per item in dynamic arrays
struct Data {
address user;
uint256 balance;
}
// slot 0 for current array length
// 2 slots per item
// a[0].user would be : keccak256(encodePacked(0)) + 0 * 2 + 0
// a[0].balance would be: keccak256(encodePacked(0)) + 0 * 2 + 1
// a[1].user would be : keccak256(encodePacked(0)) + 1 * 2 + 0
// a[1].balance would be: keccak256(encodePacked(0)) + 1 * 2 + 1
Data[] private a;
// slot 1
address private b;
Another caveat could be inheritance:
contract A {
// slot 0
address private a;
}
contract B is A {
// slot 1
address private b;
}
This could be indeed very complicated manually to count the positions and offsets, that's why I use 0xweb auto-generated classes to access private storage of contracts, which are validated at Etherscan and co. The tool generates TypeScript class to call functions (read/write) of the contract, but also it generates a storage reader class, so you can access all variables by name, for example - if your contract is validated at Etherscan, you could generate the TypeScript class as:
0xweb i 0x501... --name MyContract --chain eth
import { MyContract } from '#0xweb/eth/MyContract/MyContract'
let contract = new MyContract();
await contract.storage.a();
await contract.storage.z();
// or the first item of the array
await contract.storage.list(0);
// mapping
await contract.storage.people('0xFF01'/* bytes32 */ );
I don't believe you can. A private variable is meant to only be used within the contract in which it is defined.
See here: http://solidity.readthedocs.io/en/v0.4.21/contracts.html
Related
I can't understand how the closure works in Dart. Why does BMW stay? This explanation causes my neurons to overheat. A lexical closure is a functional object that has access to variables from its lexical domain. Even if it is used outside of its original scope.
`void main() {
var car = makeCar('BMW');
print(makeCar);
print(car);
print(makeCar('Tesla'));
print(car('Audi'));
print(car('Nissan'));
print(car('Toyota'));
}
String Function(String) makeCar(String make) {
var ingane = '4.4';
return (model) => '$model,$ingane,$make';
}`
Console
Closure 'makeCar'
Closure 'makeCar_closure'
Closure 'makeCar_closure'
Audi,4.4,BMW
Nissan,4.4,BMW
Toyota,4.4,BMW
Calling car('Audi') is equal to calling (makeCar('BMW'))('Audi');
A lexical closure is a functional object that has access to variables from its lexical domain. Even if it is used outside of its original scope.
in simple english:
String make will stay valid as long as the returned function is not out of scope because the returned function has reference to String make.
In essence, you "inject" information needed for the newly created function. Your car knows that make is "BMW"
I think I figured it out. Here is an example where I left comments. Maybe it will help someone.
void main() {
var pr = funkOut(10); // assign a reference to an object instance
// of the Function class to the pr variable. pr is a closure because
// it is assigned a reference to an instance that contains a lexical
// environment (int a) and an anonymous function from this environment.
// 10 transfer to a
print(pr(5)); // 5 transfer to b //15
print(pr(10)); // 10 transfer to b //20
pr = funkOut(20);// 20 transfer to a
print(pr(5)); // 5 transfer to b //25
print(pr); // Closure: (int) => int
}
Function funkOut(int a) {
return (int b) => a + b;
}
Will following code be executed atomically?
const int oldId = id.exchange((id.load()+1) % maxId);
Where id is std::atomic<int>, and maxId is some integer value.
I searched google and stackoverflow for std::atomic modulo increment. And I found some topics but I can't find clear answer how to do that properly.
In my case even better would be to use:
const int newId = id.exchange((++id) % maxId);
But I am still not sure if it will be executed atomically.
No, this is not atomic, because the load() and the exchange() are separate operations, and nothing is preventing id from getting updated after the load, but before the exchange. In that case your exchange would write a value that has been calculated based on a stale input, so you end up with a missed update.
You can implement a modulo increment using a simple compare_exchange loop:
int val = id.load();
int newVal = (val + 1) % maxId;
while (!id.compare_exchange_weak(val, newVal) {
newVal = (val + 1) % maxId;
}
If the compare_exchange fails it performs a reload and populates val with the updated value. So we can re-calculate newVal and try again.
Edit:
The whole point of the compare-exchange-loop is to handle the case that between the load and the compare-exchange somebody might change id. The idea is to:
load the current value of id
calculate the new value
update id with our own value if and only if the value currently stored in id is the same one as we read in 1. If this is the case we are done, otherwise we restart at 1.
compare_exchange is allows us to perform the comparison and the conditional update in one atomic operation. The first argument to compare_exchange is the expected value (the one we use in our comparison). This value is passed by reference. So when the comparison fails, compare_exchange automatically reloads the current value and updates the provided variable (in our case val).
And since Peter Cordes pointed out correctly that this can be done in a do-while loop to avoid the code duplication, here it is:
int val = id.load();
int newVal;
do {
newVal = (val + 1) % maxId;
} while (!id.compare_exchange_weak(val, newVal);
I'm doing a nested iteration over two lists, in which I am populating some StringBuffers, like this:
var int_list = [1, 2, 3];
var letters_list = ['a', 'b', 'c'];
var row_strings = List.filled(3, StringBuffer());
var single_buffer = StringBuffer();
int_list.asMap().forEach((int_index, column) {
letters_list.asMap().forEach((letter_index, letter) {
// debug the writing operation
print('writing $letter_index - $letter');
row_strings[letter_index].write(letter);
// try a buffer not in a list as a test
if (letter_index == 0) {
single_buffer.write(letter);
}
});
});
print(single_buffer);
print(row_strings);
What I expect to happen is that in the list of StringBuffers, buffer 0 gets all the 'a's, buffer 1 gets all the 'b's, and buffer 3 the 'c'.
The debug output confirms that the writing operation is doing the right thing:
writing 0 - a
writing 1 - b
writing 2 - c
writing 0 - a
writing 1 - b
writing 2 - c
writing 0 - a
writing 1 - b
writing 2 - c
and the single string buffer gets the right output:
aaa
But the output of the list is this:
[abcabcabc, abcabcabc, abcabcabc]
What is going on here? There seems to be some strange behaviour when the StringBuffers are in a list.
Your problem is this line:
var row_strings = List.filled(3, StringBuffer());
This constructor is documented as:
List.filled(int length, E fill, {bool growable: false})
Creates a list of the given length with fill at each position.
https://api.dart.dev/stable/2.10.5/dart-core/List/List.filled.html
So what you are doing is creating a single StringBuffer instance and uses that on every position in your row_strings list.
What you properly want, is to create a new StringBuffer for each position in the list. You need to use List.generate for that:
List.generate(int length,E generator(int index), {bool growable: true})
Generates a list of values.
Creates a list with length positions and fills it with values created by calling generator for each index in the range 0 .. length - 1 in increasing order.
https://api.dart.dev/stable/2.10.5/dart-core/List/List.generate.html
Using that, we end up with:
final row_strings = List.generate(3, (_) => StringBuffer());
We don't need the index argument in our generator so I have just called it _. The function (_) => StringBuffer() will be executed for each position in the list and saved. Since out function returns a new instance of StringBuffer each time it is executed, we will end up with a list of 3 separate StringBuffer instances.
Functions in Dart are first-class objects, allowing you to pass them to other objects or functions.
void main() {
var shout = (msg) => ' ${msg.toUpperCase()} ';
print(shout("yo"));
}
This made me wonder if there was a way to modify a function a run time, just like an object, prior to passing it to something else. For example:
Function add(int input) {
return add + 2;
}
If I wanted to make the function a generic addition function, then I would do:
Function add(int input, int increment) {
return add + increment;
}
But then the problem would be that the object I am passing the function to would need to specify the increment. I would like to pass the add function to another object, with the increment specified at run time, and declared within the function body so that the increment cannot be changed by the recipient of the function object.
The answer seems to be to use a lexical closure.
From here: https://dart.dev/guides/language/language-tour#built-in-types
A closure is a function object that has access to variables in its
lexical scope, even when the function is used outside of its original
scope.
Functions can close over variables defined in surrounding scopes. In
the following example, makeAdder() captures the variable addBy.
Wherever the returned function goes, it remembers addBy.
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
In the above cases, we pass 2 or 4 into the makeAdder function. The makeAdder function uses the parameter to create and return a function object that can be passed to other objects.
You most likely don't need to modify a closure, just the ability to create customized closures.
The latter is simple:
int Function(int) makeAdder(int increment) => (int value) => value + increment;
...
foo(makeAdder(1)); // Adds 1.
foo(makeAdder(4)); // Adds 2.
You can't change which variables a closure is referencing, but you can change their values ... if you an access the variable. For local variables, that's actually hard.
Mutating state which makes an existing closure change behavior can sometimes be appropriate, but those functions should be very precise about how they change and where they are being used. For a function like add which is used for its behavior, changing the behavior is rarely a good idea. It's better to replace the closure in the specific places that need to change behavior, and not risk changing the behavior in other places which happen to depend on the same closure. Otherwise it becomes very important to control where the closure actually flows.
If you still want to change the behavior of an existing global, you need to change a variable that it depends on.
Globals are easy:
int increment = 1;
int globalAdder(int value) => value + increment;
...
foo(globalAdd); // Adds 1.
increment = 2;
foo(globalAdd); // Adds 2.
I really can't recommend mutating global variables. It scales rather badly. You have no control over anything.
Another option is to use an instance variable to hold the modifiable value.
class MakeAdder {
int increment = 1;
int instanceAdd(int value) => value + increment;
}
...
var makeAdder = MakeAdder();
var adder = makeAdder.instanceAdd;
...
foo(adder); // Adds 1.
makeAdder.increment = 2;
foo(adder); // Adds 2.
That gives you much more control over who can access the increment variable. You can create multiple independent mutaable adders without them stepping on each other's toes.
To modify a local variable, you need someone to give you access to it, from inside the function where the variable is visible.
int Function(int) makeAdder(void Function(void Function(int)) setIncrementCallback) {
var increment = 1;
setIncrementCallback((v) {
increment = v;
});
return (value) => value + increment;
}
...
void Function(int) setIncrement;
int Function(int) localAdd = makeAdder((inc) { setIncrement = inc; });
...
foo(localAdd); // Adds 1.
setIncrement(2);
foo(localAdd); // Adds 2.
This is one way of passing back a way to modify the local increment variable.
It's almost always far too complicated an approach for what it gives you, I'd go with the instance variable instead.
Often, the instance variable will actually represent something in your model, some state which can meaningfully change, and then it becomes predictable and understandable when and how the state of the entire model changes, including the functions referring to that model.
Using partial function application
You can use a partial function application to bind arguments to functions.
If you have something like:
int add(int input, int increment) => input + increment;
and want to pass it to another function that expects to supply fewer arguments:
int foo(int Function(int input) applyIncrement) => applyIncrement(10);
then you could do:
foo((input) => add(input, 2); // `increment` is fixed to 2
foo((input) => add(input, 4); // `increment` is fixed to 4
Using callable objects
Another approach would be to make a callable object:
class Adder {
int increment = 0;
int call(int input) => input + increment;
}
which could be used with the same foo function above:
var adder = Adder()..increment = 2;
print(foo(adder)); // Prints: 12
adder.increment = 4;
print(foo(adder)); // Prints: 14
I am reading Richard Stevens' Advance Programming in unix environment.
There is a code in thread synchronization category (chapter - 11).
This is code showing is showing how to avoid race conditions for many shared structure of same type.
This code is showing two mutex for synch.- one for a list fh (a list which keep track of all the foo structures) & f_next field and another for the structure foo
The code is:
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define NHASH 29
#define HASH(fp) (((unsigned long)fp)%NHASH)
struct foo *fh[NHASH];
pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
struct foo {
int f_count;
pthread_mutex_t f_lock;
struct foo *f_next; /* protected by hashlock */
int f_id;
/* ... more stuff here ... */
};
struct foo * foo_alloc(void) /* allocate the object */
{
struct foo *fp;
int idx;
if ((fp = malloc(sizeof(struct foo))) != NULL) {
fp->f_count = 1;
if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
free(fp);
return(NULL);
}
idx = HASH(fp);
pthread_mutex_lock(&hashlock);
///////////////////// HERE -----------------
fp->f_next = fh[idx];
fh[idx] = fp->f_next;
//////////////////// UPTO HERE -------------
pthread_mutex_lock(&fp->f_lock);
pthread_mutex_unlock(&hashlock);
/* ... continue initialization ... */
pthread_mutex_unlock(&fp->f_lock);
}
return(fp);
}
void foo_hold(struct foo *fp) /* add a reference to the object */
.......
The doubt is
1) What is HASH(fp) pre-processor doing?
I know that it is typecasting what is fp store and then taking its modulo. But, in the function foo_alloc we are just passing the address of newly allocated foo structure.
Why we are doing this I know that this will give me a integer between 0 and 28 - to store in array fh. But why are we taking modulo of an address. Why there is so much randomization?
2) Suppose i accept that, now after this what these two lines are doing (also highlighted in the code) :
fp->f_next = fh[idx];
fh[idx] = fp->f_next;
I hope initially fh[idx] has any garbage value which i assigned to the f_next field of foo and in the next line what is happening , again the same assignment but in opposite order.
struct foo *fh[NHASH] is a hash table, and use the HASH macro as the hash function.
1) HASH(fp) calculates the index to decide where the in the fh to store fp, and it uses the address of the fp and uses the address as key to calculate the index. We can easily typecast the address to the long type.
2) Use the linked list to avoid the hash collisions called separate chaining, and I think the following cod is right, and you can check it in the book :
fp->f_next = fh[idx];
fh[idx] = fp;
insert the fp element to the header of the linked list fh[idx], and the initial value of the fh[idx] is null.