Merge pull request #4905 from ethereum/chriseth-patch-2

Update first part of example.
This commit is contained in:
chriseth 2018-09-06 17:59:38 +02:00 committed by GitHub
commit f5d289b937
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -33,14 +33,14 @@ Storage
The first line simply tells that the source code is written for
Solidity version 0.4.0 or anything newer that does not break functionality
(up to, but not including, version 0.5.0). This is to ensure that the
contract does not suddenly behave differently with a new compiler version. The keyword ``pragma`` is called that because, in general,
pragmas are instructions for the compiler about how to treat the
contract is not compilable with a new (breaking) compiler version, where it could behave differently.
So-called pragmas are common instrutions for compilers about how to treat the
source code (e.g. `pragma once <https://en.wikipedia.org/wiki/Pragma_once>`_).
A contract in the sense of Solidity is a collection of code (its *functions*) and
data (its *state*) that resides at a specific address on the Ethereum
blockchain. The line ``uint storedData;`` declares a state variable called ``storedData`` of
type ``uint`` (unsigned integer of 256 bits). You can think of it as a single slot
type ``uint`` (*u*nsigned *int*eger of *256* bits). You can think of it as a single slot
in a database that can be queried and altered by calling functions of the
code that manages the database. In the case of Ethereum, this is always the owning
contract. And in this case, the functions ``set`` and ``get`` can be used to modify
@ -49,8 +49,8 @@ or retrieve the value of the variable.
To access a state variable, you do not need the prefix ``this.`` as is common in
other languages.
This contract does not do much yet (due to the infrastructure
built by Ethereum) apart from allowing anyone to store a single number that is accessible by
This contract does not do much yet apart from (due to the infrastructure
built by Ethereum) allowing anyone to store a single number that is accessible by
anyone in the world without a (feasible) way to prevent you from publishing
this number. Of course, anyone could just call ``set`` again with a different value
and overwrite your number, but the number will still be stored in the history
@ -72,9 +72,9 @@ Subcurrency Example
The following contract will implement the simplest form of a
cryptocurrency. It is possible to generate coins out of thin air, but
only the person that created the contract will be able to do that (it is trivial
only the person that created the contract will be able to do that (it is easy
to implement a different issuance scheme).
Furthermore, anyone can send coins to each other without any need for
Furthermore, anyone can send coins to each other without a need for
registering with username and password — all you need is an Ethereum keypair.
@ -84,7 +84,7 @@ registering with username and password — all you need is an Ethereum keypair.
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
// easily readable from outside.
address public minter;
mapping (address => uint) public balances;
@ -99,12 +99,13 @@ registering with username and password — all you need is an Ethereum keypair.
}
function mint(address receiver, uint amount) public {
if (msg.sender != minter) return;
require(msg.sender == minter);
require(amount < 1e60);
balances[receiver] += amount;
}
function send(address receiver, uint amount) public {
if (balances[msg.sender] < amount) return;
require(amount <= balances[msg.sender], "Insufficient balance.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
@ -116,15 +117,15 @@ This contract introduces some new concepts, let us go through them one by one.
The line ``address public minter;`` declares a state variable of type address
that is publicly accessible. The ``address`` type is a 160-bit value
that does not allow any arithmetic operations. It is suitable for
storing addresses of contracts or keypairs belonging to external
storing addresses of contracts or of keypairs belonging to external
persons. The keyword ``public`` automatically generates a function that
allows you to access the current value of the state variable
from outside of the contract.
Without this keyword, other contracts have no way to access the variable.
The code of the function generated by the compiler is roughly equivalent
to the following::
to the following (ignore ``external`` and ``view`` for now)::
function minter() returns (address) { return minter; }
function minter() external view returns (address) { return minter; }
Of course, adding a function exactly like that will not work
because we would have a
@ -137,17 +138,17 @@ The next line, ``mapping (address => uint) public balances;`` also
creates a public state variable, but it is a more complex datatype.
The type maps addresses to unsigned integers.
Mappings can be seen as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_ which are
virtually initialized such that every possible key exists and is mapped to a
virtually initialized such that every possible key exists from the start and is mapped to a
value whose byte-representation is all zeros. This analogy does not go
too far, though, as it is neither possible to obtain a list of all keys of
a mapping, nor a list of all values. So either keep in mind (or
better, keep a list or use a more advanced data type) what you
added to the mapping or use it in a context where this is not needed,
like this one. The :ref:`getter function<getter-functions>` created by the ``public`` keyword
added to the mapping or use it in a context where this is not needed.
The :ref:`getter function<getter-functions>` created by the ``public`` keyword
is a bit more complex in this case. It roughly looks like the
following::
function balances(address _account) public view returns (uint) {
function balances(address _account) external view returns (uint) {
return balances[_account];
}
@ -162,7 +163,9 @@ a so-called "event" which is emitted in the last line of the function
listen for those events being emitted on the blockchain without much
cost. As soon as it is emitted, the listener will also receive the
arguments ``from``, ``to`` and ``amount``, which makes it easy to track
transactions. In order to listen for this event, you would use ::
transactions. In order to listen for this event, you would use the following
JavaScript code (which assumes that ``Coin`` is a contract object created via
web3.js or a similar module)::
Coin.Sent().watch({}, '', function(error, result) {
if (!error) {