summaryrefslogtreecommitdiffhomepage
path: root/solidity.html.markdown
diff options
context:
space:
mode:
authorNemil Dalal <nemild@gmail.com>2015-11-30 15:45:03 -0500
committerNemil Dalal <nemild@gmail.com>2015-11-30 15:45:03 -0500
commit700f3e7a1cb6ef5b905eac7ec3fe3aa2e713c079 (patch)
tree43d16e826fd6b75a6e424050dfc29bc38ebf6b92 /solidity.html.markdown
parent1f4738cbc75f789992270c3926cf9cdd30c4674a (diff)
Many minor updates
Diffstat (limited to 'solidity.html.markdown')
-rw-r--r--solidity.html.markdown226
1 files changed, 145 insertions, 81 deletions
diff --git a/solidity.html.markdown b/solidity.html.markdown
index 88ccd817..0fa1fddc 100644
--- a/solidity.html.markdown
+++ b/solidity.html.markdown
@@ -14,7 +14,7 @@ As Solidity and Ethereum are under active development, experimental or beta feat
```javascript
// Let's start with a simple Bank contract, before diving into to the key components of the language
-// START EXAMPLE
+// ** START EXAMPLE **
// Start with a Natspec comment (the three slashes) that can be used
// for documentation - and as descriptive data for UI elements
/// @title A simple deposit/withdrawal bank built on Bitcoin
@@ -22,31 +22,30 @@ As Solidity and Ethereum are under active development, experimental or beta feat
// All contracts are declared and named (in CamelCase)
// They are similar to 'class' in other languages (and allow capabilities like inheritance)
contract AcmeBank {
- // Declare state variables outside a function,
+ // Declare state variables outside a function,
// these are persistent throughout the life of the contract
// a dictionary that maps addresses to balances
- mapping (address => uint) balances;
+ mapping (address => uint) balances;
+
+ // the 'public' makes 'owner' externally readable by users or contracts
+ // (but not writeable) -
+ address public owner;
- // the 'public' makes 'owner' externally readable by users or contracts
- // (but not writeable), the 'constant' means this value to be
- // changed after initialization
- address public owner;
-
// Constructor, can receive one or many variables here
function AcmeBank() {
- // msg is a default variable that provides both the
+ // msg is a default variable that provides both the
// contract messager's address and amount
owner = msg.sender; // msg.sender refers to the address of the contract creator
}
-
- function deposit(uint balance) {
+
+ function deposit(uint balance) public {
balances[msg.sender] += msg.value; // no need for "this." or "self." in front of the state variable
return balances[msg.sender]; // msg.sender refers to the contract caller
}
- function withdraw(uint withdrawAmount) returns (uint remainingBalance) {
+ function withdraw(uint withdrawAmount) public returns (uint remainingBalance) {
if(balances[msg.sender] >= withdrawAmount) {
balances[msg.sender] -= withdrawAmount;
@@ -58,8 +57,9 @@ contract AcmeBank {
}
}
- // It's good practice to have a remove function, which disables this contract - but does mean that users have to trust the owner
- function remove () {
+ // It's good practice to have a remove function, which disables this
+ // contract - but does mean that users have to trust the owner
+ function remove() {
if(msg.sender == owner) { // Only let the contract creator do this
suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
}
@@ -71,29 +71,35 @@ contract AcmeBank {
}
// Fallback function
- // This function is called if invalid data is sent or ether without data;
+ // The fallback function is called if none of the other functions matches the given function identifier.
+ // It is often meant to be called when invalid data is sent or ether without data.
// Added so that ether sent to this contract is reverted if the contract fails
// otherwise, the sender loses their money; you should add this in most contracts
function () { throw; }
}
-// END EXAMPLE
+// ** END EXAMPLE **
// Now let's go through the basics of Solidity
-// 1. DATA TYPES
+// 1. DATA TYPES AND ASSOCIATED METHOD
// uint is the data type typically used for currency (there are no doubles
// or floats) and for dates
-uint x;
-int constant a = 8; // int of 256 bits, cannot be changed after instantiation
+uint x;
+
+
+// with 'constant', the compiler replaces each occurence with the acutal value
+// int of 256 bits, cannot be changed after instantiation
+int constant a = 8;
+int256 constant a = 8; // same effect as line above, here the 256 is explict
+
+// For both int and uint, you can explicitly set space in steps of 8
+// e.g., int8, int16
uint8 b;
int64 c;
-// int256 is same as int
-// For both int and uint, you can explicitly set space in steps of 8,
-// e.g., int8, int16
uint248 e;
// Type casting
-int x = int(b)
+int x = int(b);
bool b = true; // or do 'var b = true;' for inferred typing
@@ -115,21 +121,22 @@ bytes m; // A special array, same as byte[] (but packed tightly)
string n = 'hello';
// Type inference
-// var does inferred typing based on first assignment,
+// var does inferred typing based on first assignment,
// can't be used in functions parameters
var a = true;
-// there are edge cases where inference leads to a value being set (e.g., an uint 8)
+// there are edge cases where inference leads to a value being set (e.g., an uint 8)
// that is different from what the user wanted (uint16), so use carefully
// by default, all values are set to 0 on instantiation
-// Delete can be called on most types, and will set the values to 0
+// Delete can be called on most types, and will set the values to 0 by assignment
uint x = 5;
delete(x); // x is now 0
// 2. DATA STRUCTURES
// Arrays
-bytes32[] names;
+bytes32[5] nicknames; // static array
+bytes32[] names; // dynamic array
uint newLength = names.push("John"); // adding returns new length of the array
// Length
names.length; // get length
@@ -153,13 +160,13 @@ delete(balances); // deletes all elements
// Unlike languages like Javascript, you cannot iterate through all elements in
// a map, without knowing the source keys
-// Structs and enums
+// Structs and enums
struct Bank { // note the capital
address owner;
uint balance;
}
Bank b = Bank({
- owner: msg.sender,
+ owner: msg.sender,
balance: 5
});
delete(b); // set all values to 0, except any mappings
@@ -168,29 +175,39 @@ delete(b); // set all values to 0, except any mappings
enum State { Created, Locked, Inactive };
State public state; // Declare variable from enum
state = State.Created;
+// enums can be explicitly converted to ints
-// 3. Variables of note
-// storage - A persistent storage hash (does not need to be declared)
-storage['abc'] = 'def'; // maps 256 bit words to 256 bit words
+// Data locations: Memory vs. storage - all complex types (arrays, structs) have a data location
+// 'memory' does not persist, 'storage' does
+// Default is 'storage' for local and state variables; 'memory' for function parameters
-// tx - This transaction
-tx.origin // address, sender of the transaction
-tx.gasprice // uint, gas price of the transaction
+// 3. Variables of note
+// ** this **
+this; // the address of the current contract
+// 'balance' often used at the end of a contracts life to send the
+// remaining balance to a party
+this.balance;
+this.someFunction(); // calls a function externally (via a message call, not via an internal jump)
-// msg - The current message received by the contract
+// ** msg - The current message received by the contract ** **
msg.sender; // address, The address of the sender
msg.value; // uint, The amount of gas provided to this contract in wei
-msg.data // bytes, complete call data
+msg.data; // bytes, complete call data
+msg.gas; // remaining gas
-// balance of the current contract (both contract and external accounts
-// have balances) - often used at the end of a contracts life to send the
-// remaining balance to a party
-this.balance
-// block
+// ** tx - This transaction **
+tx.origin; // address, sender of the transaction
+tx.gasprice; // uint, gas price of the transaction
+
+// ** block - Information about the current block **
now // uint, current time, alias for block.timestamp
-block.number // uint, current block number
-block.difficulty // uint, current block difficulty
-block.blockhash(1) // returns bytes32, only provides for most recent 256 block
+block.number; // uint, current block number
+block.difficulty; // uint, current block difficulty
+block.blockhash(1); // returns bytes32, only provides for most recent 256 blocks
+block.gasLimit();
+
+// ** storage - A persistent storage hash (does not need to be declared) **
+storage['abc'] = 'def'; // maps 256 bit words to 256 bit words
// 4. FUNCTIONS AND MORE
// A. Functions
@@ -236,13 +253,13 @@ function b() {
// B. Events
// Events are an easy way to notify external listeners that something changed
-// You typically decalre them after your contract parameters
+// You typically declare them after your contract parameters
event Sent(address from, address to, uint amount);
// You then call it in a function, when you want to trigger it
sent(from, to, amount);
-// For an external party (a contract or external entity), to watch
+// For an external party (a contract or external entity), to watch
// for an event, you write the following:
Coin.Sent().watch({}, '', function(error, result) {
if (!error) {
@@ -254,53 +271,89 @@ Coin.Sent().watch({}, '', function(error, result) {
"Receiver: " + Coin.balances.call(result.args.to));
}
}
-// This is a common paradigm for one contract to depend on another (e.g., a
+// This is a common paradigm for one contract to depend on another (e.g., a
// contract that depends on the current exchange rate provided by another
// contract)
// C. Modifiers
-// Modifiers let you validate inputs to functions
-// The '_' (underscore) must be included, and is an indicator that the
+// Modifiers let you validate inputs to functions such as a minimal balance or user authentication
+// It's similar to a guard clause in other languages
+
+// The '_' (underscore) must be included as the last line in the function body, and is an indicator that the
// function being called should be placed there
modifier onlyBefore(uint _time) { if (now >= _time) throw; _ }
// You can then append it right after the function declaration
-function test()
- onlyBefore()
-{
-
+function changeOwner(newOwner)
+ onlyBefore(someTime)
+ {
+ owner = newOwner;
}
// 5. BRANCHING AND LOOPS
// All basic logic blocks work - including if/else, for, while, break, continue, return
// switch is not provided
-// Syntax is the same as javascript, but there is no type conversion from
-// non-boolean to boolean
-// 6. CALLING AN EXTERNAL CONTRACT
+// Syntax is the same as javascript, but there is no type conversion from
+// non-boolean to boolean, so comparison operators must be used to get the boolean value
+
+// 6. OBJECTS/CONTRACTS
+// A. Calling an external contract
contract infoFeed {
function info() returns (uint ret) { return 42; }
}
contract Consumer {
InfoFeed feed; // create a variable that will point to a contract on the blockchain
- function setFeed(address addr) {
+
+ // Set feed to an existing contract
+ function setFeed(address addr) {
// Link to the contract by creating on the address
- feed = InfoFeed(addr);
+ feed = InfoFeed(addr);
}
- function callFeed() {
- // T final parentheses call the contract, optionally adding
+
+ // Set feed based to a new instance of the contract
+ function createNewFeed() {
+ feed = new InfoFeed();
+ }
+
+ function callFeed() {
+ // T final parentheses call the contract, optionally adding
// custom value or gas numbers
feed.info.value(10).gas(800)();
}
}
+// B. Inheritance
+
+// Order matters, last inherited contract (i.e., 'def') can override parts of the previously
+// inherited contracts
+contact MyContract is abc, def("a custom argument to def") {
+
+// Override function
+
+ function z() {
+ if (msg.sender == owner) {
+ def.z(); // call overridden function
+ }
+ }
+
+ };
+
+// C. Import
+
+import "filename";
+import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
+
+// Importing is under active development and will change
+// Importing cannot currently be done at the command line
+
// 7. CONTRACT DESIGN PATTERNS
// A. Obfuscation
-// Remember that all variables are publicly viewable on the blockchain, so
+// Remember that all variables are publicly viewable on the blockchain, so
// anything that needs some privacy needs to be obfuscated (e.g., hashed)
// B. Throwing
@@ -317,26 +370,34 @@ if (!addr.send(123)) {
// Suicide
suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the address (often the creator)
+// This is a common pattern that lets the owner end the contract
+function remove() {
+ if(msg.sender == owner) { // Only let the contract creator do this
+ suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
+ }
+}
+
// D. Storage optimization
-// Reading and writing can be expensive, as data needs to be stored in the
-// blockchain forever - this encourages smart ways to use memory (eventually,
-// compilation may better handle this, but for now there are benefits to
+// Reading and writing can be expensive, as data needs to be stored in the
+// blockchain forever - this encourages smart ways to use memory (eventually,
+// compilation may better handle this, but for now there are benefits to
// planning your data structures)
// *** EXAMPLE: Let's do a more complex example ***
+
+// ** START EXAMPLE **
// [TODO: Decide what a more complex example looks like, needs a few characteristics:
// - has a 'constant' state variable
-// - has a state machine (uses modifier)
+// - has a state machine (and uses modifier)
// - sends money to an address
// - gets information from another contract (we'll show code for both contracts)
// - Shows inheritance
// - show variables being passed in on instantiation (and guard code to throw if variables not provided)
-// - Shows the swapping out of a contract
+// - Shows the swapping out of a contract address
// Ideas:
// - crowdfunding?
// - Peer to peer insurance
// ]
-
// *** END EXAMPLE ***
// Some final points
@@ -353,7 +414,7 @@ uint a = 1 finney; // 1 ether = 1000 finney
1 minutes == 60 seconds
-// You typically multiply a variable times the unit, as these units are not
+// You typically multiply a variable times the unit, as these units are not
// directly stored in a variable
uint x = 5;
(x * 1 days); // 5 days
@@ -366,22 +427,22 @@ sha3("ab", "cd");
ripemd160("abc");
sha256("def");
-// These are natspec comments, when a user is asked to confirm a transaction
-///
-/** */
+// 8. COMMON MISTAKES/MISCONCEPTIONS
+// A few common mistakes and misconceptions:
-// 8. COMMON MISTAKES
-// A few common mistakes
-// You cannot restrict a human or computer from reading the content of
+// A. You cannot restrict a human or computer from reading the content of
// your transaction or a transaction's state
-// All data to the start of time is stored in the blockchain, so you and
-// anyone can observe all previous data states
+// All data to the start of time is stored in the blockchain, so you and
+// anyone can observe all previous data stats
-// 9. TESTING
+// When you don't specify public on a variable, you are indicating that other *contracts* can't
+// read the data - but any person can still read the data
-// 10. STYLE NOTES
-// Use 4 spaces for indentation
+// TODO
+
+// 9. STYLE NOTES
+// Use 4 spaces for indentation
// (Python's PEP8 is used as the baseline style guide, including its general philosophy)
```
@@ -391,4 +452,7 @@ sha256("def");
- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/)
- [Gitter Chat room](https://gitter.im/ethereum/go-ethereum)
-Feel free to send a pull request with any edits - or email nemild -/at-/ gmail \ No newline at end of file
+## Information purposefully excluded
+- Libraries
+
+Feel free to send a pull request with any edits - or email nemild -/at-/ gmail