solidity/docs/frequently-asked-questions.rst

140 lines
4.7 KiB
ReStructuredText
Raw Normal View History

2015-12-07 20:16:25 +00:00
###########################
Frequently Asked Questions
###########################
This list was originally compiled by `fivedogit <mailto:fivedogit@gmail.com>`_.
2015-12-07 20:16:25 +00:00
***************
Basic Questions
***************
If I return an ``enum``, I only get integer values in web3.js. How to get the named values?
2016-05-25 13:54:34 +00:00
===========================================================================================
2015-12-07 20:16:25 +00:00
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 are some examples of basic string manipulation (``substring``, ``indexOf``, ``charAt``, etc)?
2016-05-25 13:54:34 +00:00
==================================================================================================
2015-12-07 20:16:25 +00:00
There are some string utility functions at `stringUtils.sol <https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol>`_
2016-05-25 14:01:26 +00:00
which will be extended in the future. In addition, Arachnid has written `solidity-stringutils <https://github.com/Arachnid/solidity-stringutils>`_.
2015-12-07 20:16:25 +00:00
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::
2015-12-07 20:16:25 +00:00
pragma solidity >=0.4.0 <0.6.0;
2015-12-07 20:16:25 +00:00
contract C {
string s;
2016-05-05 19:10:32 +00:00
2017-12-12 18:47:30 +00:00
function append(byte c) public {
2015-12-07 20:16:25 +00:00
bytes(s).push(c);
}
2016-05-05 19:10:32 +00:00
2017-12-12 18:47:30 +00:00
function set(uint i, byte c) public {
2015-12-07 20:16:25 +00:00
bytes(s)[i] = c;
}
}
Can I concatenate two strings?
==============================
2018-09-25 17:32:03 +00:00
Yes, you can use ``abi.encodePacked``::
pragma solidity >=0.4.0 <0.6.0;
library ConcatHelper {
function concat(bytes memory a, bytes memory b)
internal pure returns (bytes memory) {
return abi.encodePacked(a, b);
}
}
2015-12-07 20:16:25 +00:00
******************
Advanced Questions
******************
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>`_.
2016-03-23 21:42:01 +00:00
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 and that ``contract B`` has a ``payable`` constructor.
2016-03-23 21:42:01 +00:00
In this example::
2016-05-12 17:16:01 +00:00
pragma solidity ^0.5.0;
contract B {
constructor() public payable {}
}
2016-05-18 15:05:28 +00:00
2016-03-23 21:42:01 +00:00
contract A {
B child;
2016-05-05 19:10:32 +00:00
2017-12-12 18:47:30 +00:00
function test() public {
2016-03-23 21:42:01 +00:00
child = (new B).value(10)(); //construct a new B with 10 wei
}
}
Can a contract pass an array (static size) or string or ``bytes`` (dynamic size) to another contract?
2016-05-25 13:54:34 +00:00
=====================================================================================================
2015-12-07 20:16:25 +00:00
Sure. Take care that if you cross the memory / storage boundary,
independent copies will be created::
pragma solidity >=0.4.16 <0.6.0;
2015-12-07 20:16:25 +00:00
contract C {
2016-05-18 15:05:28 +00:00
uint[20] x;
2016-05-05 19:10:32 +00:00
2017-12-12 18:47:30 +00:00
function f() public {
2016-05-18 15:05:28 +00:00
g(x);
h(x);
}
2016-05-05 19:10:32 +00:00
function g(uint[20] memory y) internal pure {
2016-05-18 15:05:28 +00:00
y[2] = 3;
}
2016-05-05 19:10:32 +00:00
function h(uint[20] storage y) internal {
2016-05-18 15:05:28 +00:00
y[3] = 4;
}
}
2015-12-07 20:16:25 +00:00
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.
On the other hand, ``h(x)`` successfully modifies ``x`` because only
a reference and not a copy is passed.
2015-12-07 20:16:25 +00:00
2015-12-10 11:34:46 +00:00
What does the following strange check do in the Custom Token contract?
======================================================================
::
2017-05-02 15:33:46 +00:00
require((balanceOf[_to] + _value) >= balanceOf[_to]);
2015-12-10 11:34:46 +00:00
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
2015-12-10 11:34:46 +00:00
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.
2015-12-07 20:16:25 +00:00
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>`_.