1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
|
###########################
Frequently Asked Questions
###########################
This list was originally compiled by `fivedogit <mailto:fivedogit@gmail.com>`_.
***************
Basic Questions
***************
What is Solidity?
=================
Solidity is the DEV-created (i.e. Ethereum Foundation-created),
Javascript-inspired language that can be used to create smart contracts
on the Ethereum blockchain. There are other
languages you can use as well (LLL, Serpent, etc). The main points in
favour of Solidity is that it is statically typed and offers many
advanced features like inheritance, libraries, complex
user-defined types and a bytecode optimizer.
Solidity contracts can be compiled a few different ways (see below) and the
resulting output can be cut/pasted into a geth console to deploy them to the
Ethereum blockchain.
There are some `contract examples <https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts/>`_ by fivedogit and
there should be a `test contract <https://github.com/ethereum/solidity/blob/develop/test/libsolidity/SolidityEndToEndTest.cpp>`_ for every single feature of Solidity.
How do I compile contracts?
===========================
Probably the fastest way is the `online compiler <https://ethereum.github.io/browser-solidity/>`_.
You can also use the ``solc`` binary which comes with cpp-ethereum to compile
contracts or an emerging option is to use Mix, the IDE.
Create and publish the most basic contract possible
===================================================
A quite simple contract is the `greeter <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/05_greeter.sol>`_
Is it possible to do something on a specific block number? (e.g. publish a contract or execute a transaction)
=============================================================================================================
Transactions are not guaranteed to happen on the next block or any future
specific block, since it is up to the miners to include transactions and not up
to the submitter of the transaction. This applies to function calls/transactions and contract
creation transactions.
If you want to schedule future calls of your contract, you can use the
`alarm clock <http://www.ethereum-alarm-clock.com/>`_.
What is the transaction "payload"?
==================================
This is just the bytecode "data" sent along with the request.
Is there a decompiler available?
================================
There is no decompiler to Solidity. This is in principle possible
to some degree, but for example variable names will be lost and
great effort will be necessary to make it look similar to
the original source code.
Bytecode can be decompiled to opcodes, a service that is provided by
several blockchain explorers.
Contracts on the blockchain should have their original source
code published if they are to be used by third parties.
Does ``selfdestruct()`` free up space in the blockchain?
========================================================
It removes the contract bytecode and storage from the current block
into the future, but since the blockchain stores every single block (i.e.
all history), this will not actually free up space on full/archive nodes.
Create a contract that can be killed and return funds
=====================================================
First, a word of warning: Killing contracts sounds like a good idea, because "cleaning up"
is always good, but as seen above, it does not really clean up. Furthermore,
if Ether is sent to removed contracts, the Ether will be forever lost.
If you want to deactivate your contracts, it is preferable to **disable** them by changing some
internal state which causes all functions to throw. This will make it impossible
to use the contract and ether sent to the contract will be returned automatically.
Now to answering the question: Inside a constructor, ``msg.sender`` is the
creator. Save it. Then ``selfdestruct(creator);`` to kill and return funds.
`example <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/05_greeter.sol>`_
Note that if you ``import "mortal"`` at the top of your contracts and declare
``contract SomeContract is mortal { ...`` and compile with a compiler that already
has it (which includes `browser-solidity <https://ethereum.github.io/browser-solidity/>`_), then
``kill()`` is taken care of for you. Once a contract is "mortal", then you can
``contractname.kill.sendTransaction({from:eth.coinbase})``, just the same as my
examples.
Store Ether in a contract
=========================
The trick is to create the contract with ``{from:someaddress, value: web3.toWei(3,"ether")...}``
See `endowment_retriever.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
Use a non-constant function (req ``sendTransaction``) to increment a variable in a contract
===========================================================================================
See `value_incrementer.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/20_value_incrementer.sol>`_.
Get contract address in Solidity
================================
Short answer: The global variable ``this`` is the contract address.
See `basic_info_getter <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/15_basic_info_getter.sol>`_.
Long answer: ``this`` is a variable representing the current contract.
Its type is the type of the contract. Since any contract type basically inherits from the
``address`` type, ``this`` is always convertible to ``address`` and in this case contains
its own address.
What is the difference between a function marked ``constant`` and one that is not?
==================================================================================
``constant`` functions can perform some action and return a value, but cannot
change state (this is not yet enforced by the compiler). In other words, a
constant function cannot save or update any variables within the contract or wider
blockchain. These functions are called using ``c.someFunction(...)`` from
geth or any other web3.js environment.
"non-constant" functions (those lacking the ``constant`` specifier) must be called
with ``c.someMethod.sendTransaction({from:eth.accounts[x], gas: 1000000});``
That is, because they can change state, they have to have a gas
payment sent along to get the work done.
Get a contract to return its funds to you (not using ``selfdestruct(...)``).
============================================================================
This example demonstrates how to send funds from a contract to an address.
See `endowment_retriever <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
What is a ``mapping`` and how do we use them?
=============================================
A mapping is very similar to a K->V hashmap.
If you have a state variable of type ``mapping (string -> uint) x;``, then you can
access the value by ``x["somekeystring"]``.
How can I get the length of a ``mapping``?
==========================================
Mappings are a rather low-level data structure. It does not store the keys
and it is not possible to know which or how many values are "set". Actually,
all values to all possible keys are set by default, they are just
initialised with the zero value.
In this sense, the attribute ``length`` for a mapping does not really apply.
If you want to have a "sized mapping", you can use the iterable mapping
(see below) or just a dynamically-sized array of structs.
Are ``mapping``'s iterable?
===========================
Mappings themselves are not iterable, but you can use a higher-level
datastructure on top of it, for example the `iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_.
Can I put arrays inside of a ``mapping``? How do I make a ``mapping`` of a ``mapping``?
=======================================================================================
Mappings are already syntactically similar to arrays as they are, therefore it doesn't make much sense to store an array in them. Rather what you should do is create a mapping of a mapping.
An example of this would be::
contract C {
struct myStruct {
uint someNumber;
string someString;
}
mapping(uint => mapping(string => myStruct)) myDynamicMapping;
function storeInMapping() {
myDynamicMapping[1]["Foo"] = myStruct(2, "Bar");
}
}
Can you return an array or a ``string`` from a solidity function call?
======================================================================
Yes. See `array_receiver_and_returner.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/60_array_receiver_and_returner.sol>`_.
What is problematic, though, is returning any variably-sized data (e.g. a
variably-sized array like ``uint[]``) from a fuction **called from within Solidity**.
This is a limitation of the EVM and will be solved with the next protocol update.
Returning variably-sized data as part of an external transaction or call is fine.
How do you represent ``double``/``float`` in Solidity?
======================================================
This is not yet possible.
Is it possible to in-line initialize an array like so: ``string[] myarray = ["a", "b"];``
=========================================================================================
Yes. However it should be noted that this currently only works with statically sized memory arrays. You can even create an inline memory
array in the return statement. Pretty cool, huh?
Example::
contract C {
function f() returns (uint8[5]) {
string[4] memory adaArr = ["This", "is", "an", "array"];
return ([1, 2, 3, 4, 5]);
}
}
What are ``event``'s and why do we need them?
=============================================
Let us suppose that you need a contract to alert the outside world when
something happens. The contract can fire an event, which can be listened to
from web3 (inside geth or a web application). The main advantage of events
is that they are stored in a special way on the blockchain so that it
is very easy to search for them.
What are the different function visibilities?
=============================================
The visibility specifiers do not only change the visibility but also
the way functions can be called. In general, functions in the
same contract can also be called internally (which is cheaper
and allows for memory types to be passed by reference). This
is done if you just use ``f(1,2)``. If you use ``this.f(1,2)``
or ``otherContract.f(1,2)``, the function is called externally.
Internal function calls have the advantage that you can use
all Solidity types as parameters, but you have to stick to the
simpler ABI types for external calls.
* ``external``: all, only externally
* ``public``: all (this is the default), externally and internally
* ``internal``: only this contract and contracts deriving from it, only internally
* ``private``: only this contract, only internally
Do contract constructors have to be publicly visible?
=====================================================
You can use the visibility specifiers, but they do not yet have any effect.
The constructor is removed from the contract code once it is deployed,
Can a contract have multiple constructors?
==========================================
No, a contract can have only one constructor.
More specifically, it can only have one function whose name matches
that of the constructor.
Having multiple constructors with different number of arguments
or argument types, as it is possible in other languages
is not allowed in Solidity.
Is a constructor required?
==========================
No. If there is no constructor, a generic one without arguments and no actions will be used.
Are timestamps (``now,`` ``block.timestamp``) reliable?
=======================================================
This depends on what you mean by "reliable".
In general, they are supplied by miners and are therefore vulnerable.
Unless someone really messes up the blockchain or the clock on
your computer, you can make the following assumptions:
You publish a transaction at a time X, this transaction contains same
code that calls ``now`` and is included in a block whose timestamp is Y
and this block is included into the canonical chain (published) at a time Z.
The value of ``now`` will be identical to Y and X <= Y <= Z.
Never use ``now`` or ``block.hash`` as a source of randomness, unless you know
what you are doing!
Can a contract function return a ``struct``?
============================================
Yes, but only in ``internal`` function calls.
If I return an ``enum``, I only get integer values in web3.js. How to get the named values?
===========================================================================================
Enums are not supported by the ABI, they are just supported by Solidity.
You have to do the mapping yourself for now, we might provide some help
later.
What is the deal with ``function () { ... }`` inside Solidity contracts? How can a function not have a name?
============================================================================================================
This function is called "fallback function" and it
is called when someone just sent Ether to the contract without
providing any data or if someone messed up the types so that they tried to
call a function that does not exist.
The default behaviour (if no fallback function is explicitly given) in
these situations is to just accept the call and do nothing.
This is desireable in many cases, but should only be used if there is
a way to pull out Ether from a contract.
If the contract is not meant to receive Ether with simple transfers, you
should implement the fallback function as
``function() { throw; }``
this will cause all transactions to this contract that do not call an
existing function to be reverted, so that all Ether is sent back.
Another use of the fallback function is to e.g. register that your
contract received ether by using an event.
*Attention*: If you implement the fallback function take care that it uses as
little gas as possible, because ``send()`` will only supply a limited amount.
Is it possible to pass arguments to the fallback function?
==========================================================
The fallback function cannot take parameters.
Under special circumstances, you can send data. If you take care
that none of the other functions is invoked, you can access the data
by ``msg.data``.
Can state variables be initialized in-line?
===========================================
Yes, this is possible for all types (even for structs). However, for arrays it
should be noted that you must declare them as static memory arrays.
Examples::
contract C {
struct S {
uint a;
uint b;
}
S public x = S(1, 2);
string name = "Ada";
string[4] memory adaArr = ["This", "is", "an", "array"];
}
contract D {
C c = new C();
}
What is the ``modifier`` keyword?
=================================
Modifiers are a way to prepend or append code to a function in order
to add guards, initialisation or cleanup functionality in a concise way.
For examples, see the `features.sol <https://github.com/ethereum/dapp-bin/blob/master/library/features.sol>`_.
How do structs work?
====================
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_struct_and_for_loop_tester.sol>`_.
How do for loops work?
======================
Very similar to JavaScript. There is one point to watch out for, though:
If you use ``for (var i = 0; i < a.length; i ++) { a[i] = i; }``, then
the type of ``i`` will be inferred only from ``0``, whose type is ``uint8``.
This means that if ``a`` has more than ``255`` elements, your loop will
not terminate because ``i`` can only hold values up to ``255``.
Better use ``for (uint i = 0; i < a.length...``
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_struct_and_for_loop_tester.sol>`_.
What character set does Solidity use?
=====================================
Solidity is character set agnostic concerning strings in the source code, although
UTF-8 is recommended. Identifiers (variables, functions, ...) can only use
ASCII.
What are some examples of basic string manipulation (``substring``, ``indexOf``, ``charAt``, etc)?
==================================================================================================
There are some string utility functions at `stringUtils.sol <https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol>`_
which will be extended in the future. In addition, Arachnid has written `solidity-stringutils <https://github.com/Arachnid/solidity-stringutils>`_.
For now, if you want to modify a string (even when you only want to know its length),
you should always convert it to a ``bytes`` first::
contract C {
string s;
function append(byte c) {
bytes(s).push(c);
}
function set(uint i, byte c) {
bytes(s)[i] = c;
}
}
Can I concatenate two strings?
==============================
You have to do it manually for now.
Why is the low-level function ``.call()`` less favorable than instantiating a contract with a variable (``ContractB b;``) and executing its functions (``b.doSomething();``)?
=============================================================================================================================================================================
If you use actual functions, the compiler will tell you if the types
or your arguments do not match, if the function does not exist
or is not visible and it will do the packing of the
arguments for you.
See `ping.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_ping.sol>`_ and
`pong.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_pong.sol>`_.
Is unused gas automatically refunded?
=====================================
Yes and it is immediate, i.e. done as part of the transaction.
When returning a value of say ``uint`` type, is it possible to return an ``undefined`` or "null"-like value?
============================================================================================================
This is not possible, because all types use up the full value range.
You have the option to ``throw`` on error, which will also revert the whole
transaction, which might be a good idea if you ran into an unexpected
situation.
If you do not want to throw, you can return a pair::
contract C {
uint[] counters;
function getCounter(uint index)
returns (uint counter, bool error) {
if (index >= counters.length) return (0, true);
else return (counters[index], false);
}
function checkCounter(uint index) {
var (counter, error) = getCounter(index);
if (error) {
...
}
else {
...
}
}
}
Are comments included with deployed contracts and do they increase deployment gas?
==================================================================================
No, everything that is not needed for execution is removed during compilation.
This includes, among others, comments, variable names and type names.
What happens if you send ether along with a function call to a contract?
========================================================================
It gets added to the total balance of the contract, just like when you send ether when creating a contract.
Is it possible to get a tx receipt for a transaction executed contract-to-contract?
===================================================================================
No, a function call from one contract to another does not create its own transaction,
you have to look in the overall transaction. This is also the reason why several
block explorer do not show Ether sent between contracts correctly.
What is the ``memory`` keyword? What does it do?
================================================
The Ethereum Virtual Machine has three areas where it can store items.
The first is "storage", where all the contract state variables reside.
Every contract has its own storage and it is persistent between function calls
and quite expensive to use.
The second is "memory", this is used to hold temporary values. It
is erased between (external) function calls and is cheaper to use.
The third one is the stack, which is used to hold small local variables.
It is almost free to use, but can only hold a limited amount of values.
For almost all types, you cannot specify where they should be stored, because
they are copied everytime they are used.
The types where the so-called storage location is important are structs
and arrays. If you e.g. pass such variables in function calls, their
data is not copied if it can stay in memory or stay in storage.
This means that you can modify their content in the called function
and these modifications will still be visible in the caller.
There are defaults for the storage location depending on which type
of variable it concerns:
* state variables are always in storage
* function arguments are always in memory
* local variables always reference storage
Example::
contract C {
uint[] data1;
uint[] data2;
function appendOne() {
append(data1);
}
function appendTwo() {
append(data2);
}
function append(uint[] storage d) {
d.push(1);
}
}
The function ``append`` can work both on ``data1`` and ``data2`` and its modifications will be
stored permanently. If you remove the ``storage`` keyword, the default
is to use ``memory`` for function arguments. This has the effect that
at the point where ``append(data1)`` or ``append(data2)`` is called, an
independent copy of the state variable is created in memory and
``append`` operates on this copy (which does not support ``.push`` - but that
is another issue). The modifications to this independent copy do not
carry back to ``data1`` or ``data2``.
A common mistake is to declare a local variable and assume that it will
be created in memory, although it will be created in storage::
/// THIS CONTRACT CONTAINS AN ERROR
contract C {
uint someVariable;
uint[] data;
function f() {
uint[] x;
x.push(2);
data = x;
}
}
The type of the local variable ``x`` is ``uint[] storage``, but since
storage is not dynamically allocated, it has to be assigned from
a state variable before it can be used. So no space in storage will be
allocated for ``x``, but instead it functions only as an alias for
a pre-existing variable in storage.
What will happen is that the compiler interprets ``x`` as a storage
pointer and will make it point to the storage slot ``0`` by default.
This has the effect that ``someVariable`` (which resides at storage
slot ``0``) is modified by ``x.push(2)``.
The correct way to do this is the following::
contract C {
uint someVariable;
uint[] data;
function f() {
uint[] x = data;
x.push(2);
}
}
Can a regular (i.e. non-contract) ethereum account be closed permanently like a contract can?
=============================================================================================
No. Non-contract accounts "exist" as long as the private key is known by
someone or can be generated in some way.
What is the difference between ``bytes`` and ``byte[]``?
========================================================
``bytes`` is usually more efficient: When used as arguments to functions (i.e. in
CALLDATA) or in memory, every single element of a ``byte[]`` is padded to 32
bytes which wastes 31 bytes per element.
Is it possible to send a value while calling an overloaded function?
====================================================================
It's a known missing feature. https://www.pivotaltracker.com/story/show/92020468
as part of https://www.pivotaltracker.com/n/projects/1189488
Best solution currently see is to introduce a special case for gas and value and
just re-check whether they are present at the point of overload resolution.
******************
Advanced Questions
******************
How do you get a random number in a contract? (Implement a self-returning gambling contract.)
=============================================================================================
Getting randomness right is often the crucial part in a crypto project and
most failures result from bad random number generators.
If you do not want it to be safe, you build something similar to the `coin flipper <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/35_coin_flipper.sol>`_
but otherwise, rather use a contract that supplies randomness, like the `RANDAO <https://github.com/randao/randao>`_.
Get return value from non-constant function from another contract
=================================================================
The key point is that the calling contract needs to know about the function it intends to call.
See `ping.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_ping.sol>`_
and `pong.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_pong.sol>`_.
Get contract to do something when it is first mined
===================================================
Use the constructor. Anything inside it will be executed when the contract is first mined.
See `replicator.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/50_replicator.sol>`_.
Can a contract create another contract?
=======================================
Yes, see `replicator.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/50_replicator.sol>`_.
Note that the full code of the created contract has to be included in the creator contract.
This also means that cyclic creations are not possible (because the contract would have
to contain its own code) - at least not in a general way.
How do you create 2-dimensional arrays?
=======================================
See `2D_array.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/55_2D_array.sol>`_.
Note that filling a 10x10 square of ``uint8`` + contract creation took more than ``800,000``
gas at the time of this writing. 17x17 took ``2,000,000`` gas. With the limit at
3.14 million... well, there’s a pretty low ceiling for what you can create right
now.
Note that merely "creating" the array is free, the costs are in filling it.
Note2: Optimizing storage access can pull the gas costs down considerably, because
32 ``uint8`` values can be stored in a single slot. The problem is that these optimizations
currently do not work across loops and also have a problem with bounds checking.
You might get much better results in the future, though.
What does ``p.recipient.call.value(p.amount)(p.data)`` do?
==========================================================
Every external function call in Solidity can be modified in two ways:
1. You can add Ether together with the call
2. You can limit the amount of gas available to the call
This is done by "calling a function on the function":
``f.gas(2).value(20)()`` calls the modified function ``f`` and thereby sending 20
Wei and limiting the gas to 2 (so this function call will most likely go out of
gas and return your 20 Wei).
In the above example, the low-level function ``call`` is used to invoke another
contract with ``p.data`` as payload and ``p.amount`` Wei is sent with that call.
What happens to a ``struct``'s mapping when copying over a ``struct``?
======================================================================
This is a very interesting question. Suppose that we have a contract field set up like such::
struct user {
mapping(string => address) usedContracts;
}
function somefunction {
user user1;
user1.usedContracts["Hello"] = "World";
user user2 = user1;
}
In this case, the mapping of the struct being copied over into the userList is ignored as there is no "list of mapped keys".
Therefore it is not possible to find out which values should be copied over.
How do I initialize a contract with only a specific amount of wei?
==================================================================
Currently the approach is a little ugly, but there is little that can be done to improve it.
In the case of a ``contract A`` calling a new instance of ``contract B``, parentheses have to be used around
``new B`` because ``B.value`` would refer to a member of ``B`` called ``value``.
You will need to make sure that you have both contracts aware of each other's presence.
In this example::
contract B {}
contract A {
address child;
function test() {
child = (new B).value(10)(); //construct a new B with 10 wei
}
}
Can a contract function accept a two-dimensional array?
=======================================================
This is not yet implemented for external calls and dynamic arrays -
you can only use one level of dynamic arrays.
What is the relationship between ``bytes32`` and ``string``? Why is it that ``bytes32 somevar = "stringliteral";`` works and what does the saved 32-byte hex value mean?
========================================================================================================================================================================
The type ``bytes32`` can hold 32 (raw) bytes. In the assignment ``bytes32 samevar = "stringliteral";``,
the string literal is interpreted in its raw byte form and if you inspect ``somevar`` and
see a 32-byte hex value, this is just ``"stringliteral"`` in hex.
The type ``bytes`` is similar, only that it can change its length.
Finally, ``string`` is basically identical to ``bytes`` only that it is assumed
to hold the UTF-8 encoding of a real string. Since ``string`` stores the
data in UTF-8 encoding it is quite expensive to compute the number of
characters in the string (the encoding of some characters takes more
than a single byte). Because of that, ``string s; s.length`` is not yet
supported and not even index access ``s[2]``. But if you want to access
the low-level byte encoding of the string, you can use
``bytes(s).length`` and ``bytes(s)[2]`` which will result in the number
of bytes in the UTF-8 encoding of the string (not the number of
characters) and the second byte (not character) of the UTF-8 encoded
string, respectively.
Can a contract pass an array (static size) or string or ``bytes`` (dynamic size) to another contract?
=====================================================================================================
Sure. Take care that if you cross the memory / storage boundary,
independent copies will be created::
contract C {
uint[20] x;
function f() {
g(x);
h(x);
}
function g(uint[20] y) {
y[2] = 3;
}
function h(uint[20] storage y) {
y[3] = 4;
}
}
The call to ``g(x)`` will not have an effect on ``x`` because it needs
to create an independent copy of the storage value in memory
(the default storage location is memory). On the other hand,
``h(x)`` successfully modifies ``x`` because only a reference
and not a copy is passed.
Sometimes, when I try to change the length of an array with ex: ``arrayname.length = 7;`` I get a compiler error ``Value must be an lvalue``. Why?
==================================================================================================================================================
You can resize a dynamic array in storage (i.e. an array declared at the
contract level) with ``arrayname.length = <some new length>;``. If you get the
"lvalue" error, you are probably doing one of two things wrong.
1. You might be trying to resize an array in "memory", or
2. You might be trying to resize a non-dynamic array.
::
int8[] memory memArr; // Case 1
memArr.length++; // illegal
int8[5] storageArr; // Case 2
somearray.length++; // legal
int8[5] storage storageArr2; // Explicit case 2
somearray2.length++; // legal
**Important note:** In Solidity, array dimensions are declared backwards from the way you
might be used to declaring them in C or Java, but they are access as in
C or Java.
For example, ``int8[][5] somearray;`` are 5 dynamic ``int8`` arrays.
The reason for this is that ``T[5]`` is always an array of 5 ``T``'s,
no matter whether ``T`` itself is an array or not (this is not the
case in C or Java).
Is it possible to return an array of strings (``string[]``) from a Solidity function?
=====================================================================================
Not yet, as this requires two levels of dynamic arrays (``string`` is a dynamic array itself).
If you issue a call for an array, it is possible to retrieve the whole array? Or must you write a helper function for that?
===========================================================================================================================
The automatic accessor function for a public state variable of array type only returns
individual elements. If you want to return the complete array, you have to
manually write a function to do that.
What could have happened if an account has storage value(s) but no code? Example: http://test.ether.camp/account/5f740b3a43fbb99724ce93a879805f4dc89178b5
==========================================================================================================================================================
The last thing a constructor does is returning the code of the contract.
The gas costs for this depend on the length of the code and it might be
that the supplied gas is not enough. This situation is the only one
where an "out of gas" exception does not revert changes to the state,
i.e. in this case the initialisation of the state variables.
https://github.com/ethereum/wiki/wiki/Subtleties
After a successful CREATE operation's sub-execution, if the operation returns x, 5 * len(x) gas is subtracted from the remaining gas before the contract is created. If the remaining gas is less than 5 * len(x), then no gas is subtracted, the code of the created contract becomes the empty string, but this is not treated as an exceptional condition - no reverts happen.
How do I use ``.send()``?
=========================
If you want to send 20 Ether from a contract to the address ``x``, you use ``x.send(20 ether);``.
Here, ``x`` can be a plain address or a contract. If the contract already explicitly defines
a function ``send`` (and thus overwrites the special function), you can use ``address(x).send(20 ether);``.
Note that the call to ``send`` may fail in certain conditions, such as if you have insufficient funds, so you should always check the return value.
``send`` returns ``true`` if the send was successful and ``false`` otherwise.
What does the following strange check do in the Custom Token contract?
======================================================================
::
if (balanceOf[_to] + _value < balanceOf[_to])
throw;
Integers in Solidity (and most other machine-related programming languages) are restricted to a certain range.
For ``uint256``, this is ``0`` up to ``2**256 - 1``. If the result of some operation on those numbers
does not fit inside this range, it is truncated. These truncations can have
`serious consequences <https://en.bitcoin.it/wiki/Value_overflow_incident>`_, so code like the one
above is necessary to avoid certain attacks.
More Questions?
===============
If you have more questions or your question is not answered here, please talk to us on
`gitter <https://gitter.im/ethereum/solidity>`_ or file an `issue <https://github.com/ethereum/solidity/issues>`_.
|