About Ethereum
External Links
@[https://github.com/ethereum/wiki/wiki/White-Paper]
@[https://ethereum.github.io/yellowpaper/paper.pdf]
@[https://solidity.readthedocs.io/en/v0.5.0/resources.html] Solidity Resources
@[https://github.com/ethereum/wiki/wiki/JSON-RPC]

@[https://github.com/ethereum/wiki/wiki/Design-Rationale]
@[https://theethereum.wiki/w/index.php/Main_Page]
@[https://solidity.readthedocs.io/]
@[https://ethereum-magicians.org]
- Solidity top questions@ethereum.stackexchange.com
@[https://ethereum.stackexchange.com/questions/tagged/solidity?sort=votes&pageSize=15]
- Enterprise Ethereum Alliance Resources:
@[https://entethalliance.org/resources/]
- Curated list of libraries, auditing/secuirity tools, dev tools, security tutorial links,...
@[https://github.com/bkrem/awesome-solidity]
- Multipurspose Eth. Ontology
@[https://media.consensys.net/ethon-introducing-semantic-ethereum-15f1f0696986]

- EVM:
@[https://github.com/pirapira/awesome-ethereum-virtual-machine]
@[https://github.com/ethereum/go-ethereum/tree/master/core/vm]
@[https://github.com/xf00f/web3x/tree/master/web3x-evm] TypeScript implementation

- Lot of interesting repos related to Ethereum:
@[https://github.com/pirapira?utf8=%E2%9C%93&tab=repositories&q=&type=source]
Who is Who
(Forcibly incomplete but still quite pertinent list of core developers and companies)

- See also:
@[https://medium.com/ethex-market/who-are-the-core-devs-of-ethereum-part-i-beb342aaaff0]

- Vitalik Buterin, Ethereum White-Paper
  @[https://github.com/vbuterin]
  @[https://github.com/vbuterin/diagrams]

- Gavin Wood: Ethereum Co-Founder
  Ethereum Yellow Paper
@[http://gavwood.com/]
@[https://en.wikipedia.org/wiki/Gavin_Wood]
 founder of Parity Technologies 

- Joseph Lubin:
  @[https://en.wikipedia.org/wiki/Joseph_Lubin_(entrepreneur)]
  founder of ConsenSys.

- Anthony Diiorio
  @[https://anthonydiiorio.ca/]
  In 2013, Anthony Diiorio funded, and along with Charles Hoskinson,
  Mihai Alisie, and Vitalik Buterin, co-founded the smart contract
  platform Ethereum.
 
- Loredana Cirstea:
  Author of dType, seth.io, Pipeline remix plugin, ...
  @[https://github.com/loredanacirstea/articles]
  @[https://github.com/loredanacirstea?utf8=%E2%9C%93&tab=repositories&q=&type=source&language=]

- Nick Johnson "Arachnid":
  @[http://blog.notdot.net/]
  @[http://blog.notdot.net/tag/damn-cool-algorithms]
    - Arachnid Labs ("string utils")
  - Core developer on go-ethereum,
  - lead developer of ENS

- Raul Jordan, Prysmatic labs: Sharding Protocol
  minimal sharding protocol implementation.

- DApps and Solidity Development:
  - Manuel Araoz: CTO&co-founder at Zeppelin.
  - Luis Cuende: CEO and cofounder of Aragon One

  - Rob Hitchens, author of Solidity CRUD

  - b9lab Quality Blockchain Education for everyone
  - Xavier Lepretre, senior consultant at B9Lab

  - Steve Marx and Tood Proebsting:
    Authors of programtheblockchain.com with great
    tutorials about Payment Channels
    @[https://programtheblockchain.com/posts/2018/12/10/introduction-to-ethereum-payment-channels-video/]
    @[https://programtheblockchain.com/posts/2018/02/23/writing-a-simple-payment-channel/]
    @[https://programtheblockchain.com/posts/2018/03/02/building-long-lived-payment-channels]

  - Péter Szilágyi, @[https://github.com/karalabe]
    Core Puppeth developer @[https://www.youtube.com/watch?v=T5RcjYPTG9g]


- Paul Lintilhac: Quantitative Developer at ConsenSys, Alethio developer

ºEnterprise Ethereum Allianceº

StackExchange Top users:
- "Afri" Ethereum FAQ answers on Stackoverflow
  (hidden user from the Parity Team)
  Lastest activity: 2018-08-21
@[https://ethereum.stackexchange.com/users/87/afri]

Companies
- Consensys:
  Consensys techs:
  Balanc3             TravelBlocks                                 Linnia
  Cellarius           Waterloo                                     Catalyst and Hub Account Manager
  ConsenSys Academy   Panvala                                      Meridio
  Plasma              Gitcoin                                      MetaMask
  Gitcoin             Infura                                       N0d.capital
  Token Foundry       Kaleido                                      Nethereum
  Viant               Applied Researcher: Sharding                 Numia
  uPort               Applied Researcher: Sidechains (PegaSys)     OpenLaw
  Trustology          Quantitative/Qualitative Researcher          PegaSys
  TruSet              Senior Design Researcher - Ujo Music

- Ujo: Ethereum blockchain-based open music industry peer-to-peer platform built by ConsenSys.
  Ujo aims to increase transparency and efficiency in the music industry through an automated,
  decentralised rights management and payments system upon which any music service or
  application can be built. Creators and rights holders register works and their stakes in those
  works in smart contracts on the blockchain. Payments are delivered automatically and
  instantly based on that information using the self-enforcing smart contract technology. Artists
  may also publish policies for how their music may be used, facilitating an open marketplace in
  which anybody can innovate a new business model, app or service as long as they meet the
  terms of those policies.

  - Pegasys: Consensys Company with
    55+ team dedicated to enterprise grade blockchain at ConsenSys.
    focused on privacy, permissioning, scalability, and other
    features to make Ethereum production-ready.
    Developers of Pantheon

- NomiClabs (Argentina)
@[https://nomiclabs.io/]
  - Products:
    - Buidler
    - Sprawl: Permissionless and censorship resistant p2p decentrilized exchange
    @[https://github.com/SprawlNetwork/whitepaper/blob/master/Sprawl.pdf]
  - Developers:
    - Patricio Palladino: Author on ºweb3x: Typescript version of web3.jsº


- Kelido.io: SaaS Ethereum/Quorum in AWS, Azure, ...
  - Marketplace
    - APP+INTEGRATION GATEWAY   :
    - PUBLIC ETHEREUM TETHER    : Pin state proofs from your private chain to public Ether. networks
    - ETHER POOL                : Enable token economy use-cases without developing your own token
    - BLOCK EXPLORER            : Get more insights through real-time+historical snapshots of your blockchain
    - IDENTITY REGISTRY         : Bind verified digital certificates to org Ether. addresses via on-chain registry
    - IPFS FILE STORE           : Securely store data through a censorship resistant file sharing protocol
    - IDENTITY MASKING HD WALLET: Submit TXs anonymously, mask your identity+manage accounts

- OpenLaw: Create, store and exec legal agreements

- Viant.io: Model Business processes, track assets+build supply chains faster

- (JP Morgan) Quorum:
   - Felix Shnir, Quorum Core, Developer Advocate               (J.P. Morgan)
   - Patrick Nielsen, Quorum and Constellation's Lead Engineer  (J.P. Morgan)
   - Brian Marchiony Head of CIB Marketing & Communications (J.P. Morgan)
   - Amber Baldet Program Lead, Blockchain Center of Excellence (J.P. Morgan)
   - David Voell Engineering Lead, CIB Emerging Technologies    (J.P. Morgan)

-ºchain.linkº
  - @[https://chain.link/]
  - smart contracts connected to real world data, events and payments.
  - Chainlink network provides reliable tamper-proof inputs and outputs
    (aka ºORACLESº) for complex smart contracts on any blockchain,
wei,ether,..
Units
wei                         :      1 wei     ← discussion around APIs ...
gwei(shannon|nanoether|nano):   1^9  weis    ←ºgas pricesº. Ex. web3j default gas price is 22 gwei
szabo|microether|micro      :   1^3  gweis
finney|milliether|milli     :   10^6 gweis   ← micropayments
ether                       :   1^9  gweis   ← main unit
kether(grand|einstein)      :   1^3  ethers
mether                      :   1^6  ethers
gether                      :   1^9  ethers
tether                      :   1^12 ethers
Network Versions
@[https://en.wikipedia.org/wiki/Ethereum#Milestones]
ºPublic Ethereum Network versionsº
Homestead → Metropolis → Serenity ("Ethereum 2.0")→

Homestead : January 2016, ~80% complete
            block reward set to 5 ether

Metropolis Part 1,Byzantium     :
 - "Ethereum" for the masses.
Metropolis Part 2,Constantinople:
 - (Aka "Ethereum 2.0"):
 - Lay the fundations of PoS(Casper consensus)
   According to @[https://www.trustnodes.com/2019/06/15/ethereum-2-0-planned-for-launch-on-the-3rd-of-january-2020]
   ...Phase zero of ethereum 2.0, which enables Proof of Stake (PoS),
   is targeted to launch on theº2020-01-03º.
   - spec freeze: June 30th
   For new realistic targets, there are two milestones.
   - First, the deposit contract is to launch ahead
     of the genesis block to allow validators to make deposits.
     .. They’re hoping at least 2 million eth will be deposited
   - Second milestone is the genesis block launch on the day
     Satoshi Nakamoto did so for bitcoin.
   This would allow three months of deposits to accumulate
   and 7 months from today for at least two clients to reach
   production status, Drake said.
   ^^^^^^^^^^^^^^^^^
   production status == """there has been a long running cross
                           client testnet that has gone through
                           security audit, fuzzing, parts have
                           gone through formal verification, and
                           hasn’t suffered major issues for a
                           healthy amount of time."""

 - ... Ethereum was able to successfully execute a hard fork called Byzantium.
   As part of this hard fork ºincreased anonymity was provided through Zero-knowledge proofsº,
   or zk-snark proofs. It also included more predictable gas charges which were becoming
   difficult to calculate with the increased number of ICOs.
   InfoQ previously covered this hard fork
   - https://www.infoq.com/news/2017/08/Ethereum-HardFork

Serenity: 
  - Ethereum 2.0 "last phase",
  - one key principle: switch to proof of stake
  - huge upgrades on the scalability side (sards, ...)

   - Ethereum 2.0 phases
     - REF: @[https://medium.com/alethio/ethereum-2-0-terms-demystified-8398357429d7]
            2019-08-13
     - Phase 0 — The beacon chain
       - managing validators and stakes
       - organizing and electing committees and proposers
       - applying consensus rules
       - rewarding and penalizing/slashing
     - Phase 1 — Shards
       - constructing the shard chains and blocks
       - anchoring (cross-linking) shard blocks to beacon chain
       - ability to do bETH transfers between validators (this might come
         sooner as it’s not technically linked to work on sharding)
     - Phase 2 — Execution Environments
       - Ewasm based virtual machine for execution of the… execution environments
       - every shard has access to all execution environments
       - ability to make transactions within execution environments
       - ability to run and interact with smart contracts
       - cross-shard communication


2018/06/17 Casper and sharding merger confirmed

2019-02-22: @[https://blog.ethereum.org/2019/02/22/ethereum-constantinople-st-petersburg-upgrade-announcement/]
- scheduled upgrade at block number 7,280,000,  predicted on 2019-02-28.

- Constantinople and St. Petersburg are the names given to this network upgrade.
  Previous network upgrades have been given other names such as Spurious Dragon and Byzantium.
  The reason that this network upgrade has two names is because the original Constantinople
  network upgrade was postponed and two protocol upgrades will need to occur on the same
  block number in order to fix issues on various Ethereum test networks, such as Ropsten.

- As a node operator or miner, what do I need to do?
  Download the latest version of your Ethereum client:
    Latest geth client (v1.8.23)
    Latest Parity client (v2.2.10-stable)
    Latest Harmony client (v2.3 Build 74)
    Latest Pantheon client (v0.9.1)
    Latest EthereumJS VM client (v2.6.0)
    Latest version of Nethermind client (v0.9.4)
    Latest version of Trinity client (v0.1.0-alpha.23)
    Latest version of Ethereum Wallet/Mist (v0.11.1)


Related:
List of Chain ID's:
@[https://chainid.network/]
@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids]
CHAIN_ID    Chain(s)
1           Ethereum mainnet
2           Morden (disused), Expanse mainnet
3           Ropsten
4           Rinkeby
30          Rootstock mainnet
31          Rootstock testnet
42          Kovan
61          Ethereum Classic mainnet
62          Ethereum Classic testnet
1337        Geth private chains (default)


Related Taxonomies
Laws Taxo.
@[https://law.stackexchange.com/tags]

Economics Taxo.
@[https://economics.stackexchange.com/tags]
Semantic chain
Seth.one
@[http://seth.one/]
@[https://www.youtube.com/playlist?list=PL4S-ERdT4ERo-2zbl4CtkFYFkR5SPVlgI]
EVM
Accounts
@[http://www.ethdocs.org/en/latest/contracts-and-transactions/account-types-gas-and-transactions.html]
 ºAccountº  ← same address space both for contract and normal accounts
┌──────────────────┐           ┌──────────────────────────────────────┬───────────────────────────────────────┐
│bytes[32]ºaddressº│           │   EXTERNALLY OWNED ACCOUNT           │          CONTRACT ACCOUNTS            │
├──────────────────┤┌──────────┼──────────────────────────────────────┼───────────────────────────────────────┤
│wei      ºbalanceº││CREATION  │→ Generate random 32bytes private key │→Create smart─contract source code  *1 │
├──────────────────┤│          │→ Generate Pub.Key from Priv.Key      │→Generate bytecode by compiling source │
│Map˂256b,256b˃    ││          │→ Generate public address as:         │→Send "Contract Creation" TX for mining│
│         ºstorageº││          │  bytes[32] pub.addr = hash(pub.addr) │→keep Contract address once "published"│
└──────────────────┘│          │                                      │ (determined from nonce)               │
                    ├──────────┼──────────────────────────────────────┼───────────────────────────────────────┤
                    │CONTROLLED│Private Key: Only the (human) owner of│ BYTECODE                              │
                    │BY        │the ºsecretº private key can decrease │                                       │
                    │          │the balance by signing a new TX       │                                       │
                    ├──────────┼──────────────────────────────────────┼───────────────────────────────────────┤
                    │FEATURES  │ bytes[32] address                    │ bytes[32] address *1                  │
                    │          │                                      │ Map˂256b,256b˃ storage *2             │
                    ├──────────┼──────────────────────────────────────┼───────────────────────────────────────┤
                    │ADDRESS   │ Generated deterministically from     │ Generated deterministically from      │
                    │          │ priv.key (→ pub.key → hash(pub.key)  │ priv.key , bytecode,  TX.nonce        │
                    └──────────┴──────────────────────────────────────┴───────────────────────────^───────────┘
                                                                  - It's recomended to change the nonce when deploying
                                                                    to two or more different networks, since there is 
                                                                    a small but finite possibility, that TXs can be 
                                                                    replayed on such networks.
                                                                  - For private networks contracts can also be deployed
                                                                    in the genesis.json block assigned to any arbitrary
                                                                    (easy-to-remember) address. 

 *2: account.storage: Persistent memory area
     - It is not possible to enumerate storage from within a contract
     - It is comparatively costly to read and even more so, to modify storage
       in the context of an (update state) TX. (It's still free of cost during
       external query calls).
     - A contract can neither read nor write to any storage apart from its own

Signing transactions Flow:
 - Identify the next available nonce for the sender account
 - Create the RawTransaction object
 - Encode the RawTransaction object using Recursive Length Prefix encoding
 - Sign the RawTransaction object
 - Send the RawTransaction object to a node for processing

Theºnonceºis an increasing numeric value which is used to uniquely identify
transactions.ºA nonce can only be used once and until a transaction is mined,º
it is possible to send multiple versions of a transaction with the same nonce,
however, once mined, any subsequent submissions will be rejected.
Message Calls
Message Calls
-------------
sender
target(can be==sender)
payload
ether
gas
return data
- Contracts can user message calls to call other contracts or send Ether to
 non-contract accounts.
 Every transaction consists of a top-level message call which in turn can
 create further message calls.
 Contracts can decide how much of its remaining gas should be sent with the
 inner message call and how much it wants to retain. If an out-of-gas
 exception happens in the inner call (or any other exception), this will be
 signalled by an error value put onto the stack. In this case, only the gas
 sent together with the call is used up. In Solidity, the calling contract
 causes a manual exception by default in such situations, so that exceptions
 "bubble up" the call stack.
 Calls depth is limited to 1024 (Loops must be used over recursive calls)
 After finished execution, contracts can return data stored at a
 preallocated location in the caller’s memory.

- Delegatecall (See libraries): Special variant of a message call, is
 identical to a message call apart from the fact that the code at the target
 address is executed in the context of the calling contract and msg.sender
 and msg.value do not change their values.
 This means that a contract can dynamically load code from a different
 address at runtime.
- Storage, current address and balance still refer to the calling contract,
  only the code is taken from the called address.
  This makes it possible to implement the “library” feature in Solidity:
  Reusable library code that can be applied to a contract’s storage in order
  to e.g. implement a complex data structure.
  EVM Summary
- TODO: EVM Illustrated
  @[https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf]
- TODO: @[https://kauri.io/article/766e5d1e1ba240a7976943b659a871fc/v1/a-deep-dive-into-the-ethereum-virtual-machine-(evm)-part-2:-memory-and-storage]
- TODO: Awesome EVM list:
@[https://github.com/pirapira/awesome-ethereum-virtual-machine]

 ºOpcodes:º
@[https://github.com/crytic/evm-opcodes]
- EVM is a 256bit machine. It is most natural to manipulate data in chunks of 32 bytes.
- Persistent storage is quite expensive.
- The Solidity compiler makes interesting choices in order to minimize gas usage.

- To interact with a Smart Contract, you send it raw bytes.
- It does some computation, possibly changing its own state,
  and then sends you raw bytes in return.
- Method calling does not actually exist. It is a collective
  illusion created by the ABI.
- The ABI is specified like a low-level format, but in function
  it's more like a serialization format for a cross-language RPC framework.
- We could draw analogies between the architectural tiers of DApp and Web App:
  - The blockchain is like the backing database
  - A contract is like a web service
  - A transaction is like a request
  - ABI is the data-interchange format, like Protocol Buffer


ºEVM Events:º
 - In the wild, there are three main uses for event logs:
   - As ersatz return values, because a transaction does not record a method's return values.
   - As a kind of cheaper alternative data storage, as long as the contract does not need access to it.
   - Events that DApp clients can subscribe to.
 - Event logging map to EVM logging primitives.
   event Deposit( address indexed _from, bytes32 indexed _id, uint _value);
 -ºEvent limitationsº:
   - There may be at most 3 indexed parameters.
   - If the type of an indexed parameter is larger than 32 bytes,
     only the KECCAK256 digest of the data is stored.
 -  EVM Log Primitives
   - log0, log1, ..., log4 EVM instructions.
 - The EVM logging facility uses different terminologies than Solidity:
   "topics": There may be up to 4 topics exactly 32 bytes each
            Solidity consumes one topic for the event's signature so only 3 are available
   "data"  : Payload of the event. It may be arbitrary number of bytes

 - Bloom filters are used to speed up search-by-topic

*EVM Memory:
- A contract obtains a freshly cleared instance for each message call
- Memory is linear and can be addressed at byte level
- ºReads are limited to a width of 256 bitsº
- ºWrites can be either 8 bits or 256 bits wideº
- Memory is expanded by a word (256-bit), when accessing
    (either reading or writing) a previously untouched memory word (ie.
    any offset within a word). At the time of expansion, the cost in gas
    must be paid. Memory is more costly the larger it grows (it scales
    quadratically)
- calldata: Separate area of memory whe message call payload is placed

ºEVM Stack:º
- EVM memory area list of 256bits up to 1024 elements used for computations
- The 16 topmost elements can be moved to the top or swaped wih the top element
- All other operations take the topmost one (or two, or more) elements and push
  the result onto the stack
- top elements can be moved to/from storage/memory, but deeper elements can
  be accessed without first removing elements on top of them.

- (EVM)full computational state: can be defined by the tuple:
  (block_state, transaction, message, code, memory, stack, pc, gas)
  block_state = global state = all accounts (balances + storage)

- selfdestruct(target): Destructor for contract @ address
  - Remaining Ethers are sent to target
  - storage ⅋ code are removed from the blockchain state
Instructions
@[https://github.com/ethereum/go-ethereum/blob/master/core/vm/instructions.go]
The all take  (in to go VM implementation) next parameters:
(pc ºuint64, iºEVMInterpreter, cºContract, memºMemory, stack *Stack)
and return ([]byte, error)
 1 opAdd        11 opLt      21 opAddmod  31 opCallValue      41 opExtCodeHash 51 opMstore   61 opCreate
 2 opSub        12 opGt      22 opMulmod  32 opCallDataLoad   42 opGasprice    52 opMstore8  62 opCreate2
 3 opMul        13 opSlt     23 opSHL     33 opCallDataSize   43 opBlockhash   53 opSload    63 opCall
 4 opDiv        14 opSgt     24 opSHR     34 opCallDataCopy   44 opCoinbase    54 opSstore   64 opCallCode
 5 opSdiv       15 opEq      25 opSAR     35 opReturnDataSize 45 opTimestamp   55 opJump     65 opDelegateCall
 6 opMod        16 opIszero  26 opSha3    36 opReturnDataCopy 46 opNumber      56 opJumpi    66 opStaticCall
 7 opSmod       17 opAnd     27 opAddress 37 opExtCodeSize    47 opDifficulty  57 opJumpdest 67 opReturn
 8 opExp        18 opOr      28 opBalance 38 opCodeSize       48 opGasLimit    58 opPc       68 opRevert
 9 opSignExtend 19 opXor     29 opOrigin  39 opCodeCopy       49 opPop         59 opMsize    69 opStop
10 opNot        20 opByte    30 opCaller  40 opExtCodeCopy    50 opMload       60 opGas      70 opSuicide

*following functions are used by the instruction jump  table */
// make log instruction function
makeLog(size int)
opPush1
makePush(size uint64, pushByteSize int)
makeDup(size int64)  // make dup instruction function
makeSwap(size int64) // make swap instruction function
CALL/
CALLCODE/
DELEGATECALL
@[https://ethereum.stackexchange.com/questions/3667/difference-between-call-callcode-and-delegatecall]

D CALL     → E: code runs in the context of E, E_storage is used

D CALLCODE → E: code runs in the context of D. D_storage is used
                                               msg.sender is D

C CALL     → D: D DELEGATECALL E:ºmsg.sender inside E is C.º
                  ^^^^^^^^^^^^^^
                  Homestead+
                 "I'm a contract and I'm allowing (delegating) you to do
                  whatever you want to my storage.
                  DELEGATECALL is a security risk for the sending contract
                  which ºneeds to trust that the receiving contractº will
                  treat the storage well."


DELEGATECALL is used to implement Libraries.
Code is deployed once at a specific address
and their code is reused using the DELEGATECALL
In comparison to contracts:
  - No state variables
  - Cannot inherit nor be inherited
  - Cannot recieve Ether
ABI Spec
Full reference:@[https://solidity.readthedocs.io/en/latest/abi-spec.html]

- The encoding is not self describing and thus requires a schema in order to decode.
- Interface functions of a contract are strongly typed
  (known at compilation time and static)
- All contracts will have the interface definitions of any contracts they call a
  vailable at compile-time.
- Data is encoded according to its type

˂b˃FUNCTION SELECTOR:˂/b˃
- Keccak-256(hash-of-function-signature)[0,1,2,3]
                     ^------+---------^  ^^^^^^^
                            |            first 4 bytes of keccak256
                            |
                   - canonical expression of the
                     basic prototype without data
                     location specifier :=
                     funct.name with the parenthesised
                     list of parameter types split by a
                     single comma (spaces removed).
                   - Return type is ºNOTº part of sign.
                     → No overriding by return type allowed.
                     (this help to keep function call
                      resolution context-independent)

˂b˃ARGUMENT (and return value) ENCODING:˂/b˃
- Starting from fifth byte

- ºELEMENTARY TYPESº:
  - uint˂M˃ : unsigned                integer type of 8,16,24,...256 bits,
  -  int˂M˃ : two's complement signed integer type of 8,16,24,...256 bits,
  - address : typed uint160 (function selector uses address not uint160)
  - bool    : typed uint8 restricted to values 0, 1.
  -  fixed˂M˃x˂N˃: "M / (10 ºº N)" value signed fixed-point decimal number
                   M bits from 8,16,...256
                   N bits from 0,8,...80
  - ufixed˂M˃x˂N˃: unsigned variant of fixed˂M˃x˂N˃.
  - fixed,   : synonyms for fixed128x18, ufixed128x18 respectively.
    ufixed
  - bytes˂M˃: binary type of M bytes, 0 ˂ M ˂= 32.
  - function: an address (20 bytes) followed by a function selector (4 bytes).
              Encoded identical to bytes24.

- º(fixed-size) arrayº:
  ˂type˃[M]: a fixed-length array of M elements, M ˃= 0, of the given type.

- ºnon-fixed-size types existº:
  - bytes   : dynamic sized byte sequence
  - string  : dynamic sized unicode string assumed to be UTF-8 encoded
  - ˂type˃[]: a variable-length array of elements of the given type

- ºtuple:º (or tuples of tuples, arrays of tuples,...)
  - (T1,T2,...,Tn): tuple consisting of the types T1, …, Tn, n ˃= 0

- ºMapping Solidity to ABI types:º
Solidity     ABI Type
contract     address
enum         smallest uint type large enough to hold all values
struct       tuple

ºFormal Specification of the Encodingº
- We distinguish two types:
  - static : encoded in-place.
  - dynamic: encoded at a separately allocated location after the current block.
             - bytes
             - string
             - T[] for any T
             - T[k] for any dynamic T and any k ˃= 0
             - (T1,...,Tk) if Ti is dynamic for some 1 ˂= i ˂= k

- Definitions:
  - len(a) :  (uint256) number of bytes in a binary string a
  - enc    :  actual encoding binary string:
              ABI_type_Value → enc(ABI_type_Value)
                               ^^^^^^^^^^^^^^^^^^^
                           len(enc(ABI_type_Value)) depends on:
                               - ABI_type_Value if type of ABI_type_Value is dynamic.
                               - ABI_type       if type of ABI_type_Value is  static.

ºExamplesº

Given the contract:

pragma solidity ˃=0.4.16 ˂0.7.0;

contract Foo {
  function bar(bytes3[2] memory) public pure {}
  function baz(uint32 x, bool y) public pure returns (bool r) { r = x ˃ 32 || y; }
  function sam(bytes memory, bool, uint[] memory) public pure {}
}

Function call to FooInstance.baz(69, true)
                                                            0xcdcd77c0: the Method ID. 4 bytes of Keccak("baz(uint32,bool)")
    0x0000000000000000000000000000000000000000000000000000000000000045: uint32 "   69-value" left-padded
    0x0000000000000000000000000000000000000000000000000000000000000001: uint32 " true-value" left-padded

Function return:
    0x0000000000000000000000000000000000000000000000000000000000000000: uint32 "false-value" left-padded


Function call to FooInstance.bar("abc", "def")
                                                            0xfce353f6: the Method ID. 4 bytes of Keccak("bar(bytes3[2])")
    0x6162630000000000000000000000000000000000000000000000000000000000: bytes3 "abc" left-aligned
    0x6465660000000000000000000000000000000000000000000000000000000000: bytes3 "abc" left-aligned

Function call to FooInstance.dave("dave", true and [1,2,3])
                                                            0xa5643bf2: the Method ID. 4 bytes of Keccak(sam(bytes,bool,uint256[]))
    0x0000000000000000000000000000000000000000000000000000000000000060: location of data-part of  first ºdynamic-typeº parameter
                                                                        measured in bytes from the start of the arguments block.
    0x0000000000000000000000000000000000000000000000000000000000000001: boolean true
    0x00000000000000000000000000000000000000000000000000000000000000a0: location of data-part of  first   ºthird-typeº parameter
                                                                        measured in bytes from the start of the arguments block.
                                                                        first dynamic-argument:
    0x0000000000000000000000000000000000000000000000000000000000000004: length of the byte array in elements
    0x6461766500000000000000000000000000000000000000000000000000000000: contents of the first argument
                                                                        second dynamic-argument:
    0x0000000000000000000000000000000000000000000000000000000000000003: length of the array in element
    0x0000000000000000000000000000000000000000000000000000000000000001: - first entry
    0x0000000000000000000000000000000000000000000000000000000000000002: - second entry
    0x0000000000000000000000000000000000000000000000000000000000000003: - third entry


ºEvents ABI Encodingº
- Log entries provide the contract's address,
- Up to four topics
- some arbitrary length binary data.

Given an event name and series of event parameters, we split them into two sub-series:
 - indexed     parameters: used in Keccak-event-signature to form the topics of the log entry.
 - non-indexed parameters: byte array of the event.

In effect, a log entry using this ABI is described as:
 - contract_address (emiting the event)

 - topics[0]: keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")

 - topics[n]: abi_encode(EVENT_INDEXED_ARGS[n - 1])
                         ^^^^^^^^^^^^^^^^^^
                       EVENT_ARGS that are indexed

 - data     : ABI encoding of EVENT_NON_INDEXED_ARGS


- if type-byte-length ˂= 32 → value padded/sign-extended          to 32 bytes is included
- if type-byte-length ˃  32 → Keccak hash of a special in-place encoded value is included
                        º     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^               º
                        º- This allows applications to efficiently query for keyccak(value) º
                        º  of dynamic-length types                                          º
                        º  but leaves applications unable to decode indexed values they haveº
                        º  not queried for                                                  º
                        º- Use the same dynamic value repeated in index and non-index event º
                        º  fields for full functionallity.                                  º
Events ⅋ LOGS
BEST PATTERNS:
- External clients must be able to restore current contract state
  by just reading events.
- Ethereum can return just a very limited information in each
  read-only query. (Up to 7 fields). That means that reports and
  data-analysis must be done on event logs.
- Contract/s state/s must be consulted only by code originated by
  a new transaction trying to update the current state.

- Logs: It is possible to store data in a specially indexed data structure
  that maps all the way up to the block level.
  This feature called 'logs' is used to implement events.
- Contracts ºCAN NOTº access log data after it has been created, but they
  can be efficiently accessed from outside the blockchain. 
  Since some part of the log data is stored in bloom filters,
  it is possible to search for this data in an efficient and cryptographically
  secure way, so network peers that do not download the whole blockchain
  ("light clients") can still find these logs.
- Logs were designed to be a form of storage that costs significantly
  less gas than contract storage:
  Logs basically[3] cost 8 gas per byte, whereas contract storage costs 20,000 gas per 32 bytes.
  Up to 3 parameters can be indexed.

ºEvent Limits:º
- Up to 3 indexed fields.
- Up to 7 fields (indexed + non-indexed fields)
- The size limit of one event is a function of the block's gas limit,
  ~ 3_145_192 (first seven digits of pi * 2)
  With a gas costs of 76 gas per byte limit is about 41kb per log event.
  REF:  Storing compressed text in Ethereum transaction logs

ºSolidity code:º
event EventDepositLog(
    uint256 indexed _market,  ← Up to 3 indexes
    address indexed _sender,    Strings, arrays can ºNOTº be used in indexes
    uint256 _amount,            (will be automatically replaced by its hash)
    uint256 _time);

ºJS Client Log monitoring:º
var myEventMonitor =
  myContract.MyEventNameLog(
     {_sender: userAddress },           // ← filter by idx sender
     {fromBlock: 0, toBlock: 'latest'}  // ← filter by block range*1
  );                                         if ommited observe
                                             "real-time" events

myEventMonitor.watch(                  // ← Start watching
  (err, result) =˃ {
    if (err) { ...    return; }
    console.log(
         "_market:"+result.args._market
       + "_sender:"+result.args._sender );
  }
)
....
myEventMonitor.stopWatching()          // ← Stop watching
Transactions
Transaction
-------------
address sender
target
payload        "message" sent from src. account to a target (account or code)
wei ether

wei gasPrice
wei gas

return data


- Note that a TX in blockchain is an intention to modify the state of the ddbb.
  It's up to the consensus algorithm to decide when and/or whether the TX will
  be accepted:
  transaction.target := address | code | "zero-account"

if target == code
   → code is executed
      input data = transaction.payload
if target == "zero.."
   → step 1: new contract created
     step 2: transaccion.payload is executed
     step 3: exec. output stored as contract.code
     (→ trans.payload == code factory of contract code)

- transaction.ether: Price in Wei of one unit of gas, in which VM operations are priced.
- The product of gasPrice and gas represents the maximum amount of Wei we are
  willing to pay for executing the transaction. gasPrice is used by miners to
  rank transactions for inclusion in the blockchain.

- transaction.gas: Its purpose is to limit the amount of work needed to execute the transaction
  and to pay for this execution.
- transaction creator (sender?) chooses the gas to pay.
    - If execution gas ˂ transaction.gas =˃ Refund to sender
    - If execution gas ˃ transaction.gas =˃ out-of-gas exception triggered
        (reverts all modifications made to the state in current call frame)

- nonce: increasing numeric value which is used to uniquely identify transactions.
  A nonce can only be used once and until a transaction is mined, it is possible
  to send multiple versions of a transaction with the same nonce, however,
  once mined, any subsequent submissions will be rejected.
  A repeated nonce can be used to overwrite a pending TX.

ºblock validation algorithm (Consensus)º
- Check if the previous block referenced exists and is valid
- Check that the timestamp of the block is greater than that of the referenced previous
  block and less than 15 minutes into the future.
- Check that the block number, difficulty, transaction root, uncle root and gas limit
  (various low-level Ethereum-specific concepts) are valid.
- Check that the proof of work on the block is valid
- Let S[0] be the STATE_ROOT of the previous block
- Let TX be the block's transaction list, with n transactions. For all "i" in
  0,...n-1, set S[i+1] = APPLY (S[i],TX[i]). If any applications returns an error, or
  if the total gas consumed in the block up until this point exceeds the GASLIMIT,
  return an error
- Let S_FINAL be S[n], but adding the block reward paid to the miner
- Check if S_FINAL is the same as the STATE_ROOT. If it is, the block is valid;
      otherwise, it is not.
- Note: coinbase: In a mining node indicates the address where rewards will go.
  Must be set to an account owned by miner

TX Signing
REF:
@[https://medium.com/@angellopozo/ethereum-signing-and-validating-13a2d7cb0ee3]
@[https://github.com/ethereum/EIPs/issues/191]

- Ethereum uses SECP256K1 for signature.
  Note:
  - secp256k1 public key is composed of two integers
    (output of an ECDSA signature): (r, s).
  - The secp256k1 ETH/BTC library, however, defines the public key as
    (r||s||v), where v = 0 or 1. 
           ^        ^^^^^^^^^^^                              
     when you derive the public keyºfrom the signatureº, two solutions surge.
     v will tell which one is the right one.
     - if length of the public key is 64 bytes (not hex encoded) r||s is used.
       if length is 65 bytes, r||s||v will be used.
     - v is the recovery id.
  - More info at @[https://bitcoin.stackexchange.com/questions/38351/ecdsa-v-r-s-what-is-v]
    Ethereum makes further adjustments to v in order to prevent replay attack as explained in
    @[https://github.com/ethereum/EIPs/issues/155]]

  - In the SmartContract we can use: 
    ecrecover Solidity Global Crypto Funct:
    ecrecover (bytes32 hash, uint8 v, bytes32 r, bytes32 s)
      returns (address): recover the address associated with the public key
                         from elliptic curve signature or return zero on error
    
    
  - The use of Curve25519 with Schnoorr signing scheme (Ed25519) is under discussion


Ether TXs in Solidity:
addressInstance.balance (uint256): balance in Wei
addressInstance.transfer(uint256 amount):
    msg.sender →(amount in wei) → addressInstance
    throws on failure

addressInstance.send(uint256 amount): returns (bool):
    msg.sender ->(amount in wei) ->addressInstance
    returns true/false, does NOT throw an exception

- In addressInstance.transfer (or send), if addressInstance
  is a contract address, its code (more specifically: its fallback function, if present)
  will be executed together with the transfer call. This is a limitation of the EVM and
  cannot be prevented. 
  If that execution runs out of gas or fails in any way, the Ether transfer will be
  reverted and the current contract will stop with an exception.
Gas Price/TX Price
- Gas (defined in the [Ethereum-Yellow-Paper]) is a virtual pricing
  mechanism for transactions andsmart contracts that is implemented
  by Ethereum to protect against Denial of Service attacks and
  resource-consumption attacks by compromised, malfunctioning or
  malicious nodes.
  (Enterprise Ethereum provides additional tools to reduce security
   risks, such as more granular permissions foractions in a network).
  REF:
  Gas rationale:
  @[https://github.com/ethereum/wiki/wiki/Design-Rationale#gas-and-fees]
  Instruction cost
  @[https://blog.qtum.org/diving-into-the-ethereum-vm-6e8d5d2f3c30]"
- Price cost applies to public network and (optionally)
  to private/consortium networks.
- Notic private/consortium networks will still be constrained to
  gas limits per TX and/or block even if the gas price is ZERO.
  TXs will fail if the consume too much gas ("CPU" or storage)
  but users will not loose any ethers in this case.
The most expensive operations by far are storage usage:
- sstore costs 20000 gas for first write to a new position
- sstore costs  5000 gas for subsequent writes to an existing position
- sload  costs   500 gas
- Most instructions costs 3~10 gases.
- Gas costs are set somewhat arbitrarily, and could well change in
  the future. As costs change, compilers would make different choices.

TX cost: REF
- 21000 paid for every transaction.
-     4 paid for every zero byte of data or code for a transaction.
-    68 paid for every non-zero byte of data or code for a transaction.

- Small negative numbers are mostly 1s, costing you quite a lot of gas.

Logging Gas Costs:  REF
  - The gas costs for the logging primitives depends on how many topics you have and how much data you log:
    (constants are defined in protocol_params)

LogDataGas       uint64 = 8   // Per byte in a LOG operation's data
topicLogTopicGas uint64 = 375 // Per LOG
LogGas           uint64 = 375 // Per LOG operation
MemoryGas        uint64 = 3    // Per byte of memory used

If you are passing in the log data as calldata to a TX,
you’ll need to pay for the transaction data too. The gas costs for calldata are:

TxDataZeroGas      uint64 = 4     // zero tx data abyte
TxDataNonZeroGas   uint64 = 68    // non-zero tx data byte

Assuming all 32 bytes are non-zero, this is still a lot cheaper than storage:

// cost of 32 bytes of log data
32 * 68 = 2176 // tx data cost
32 *  8 =  256 // log data cost
32 *  3 =   96 // memory usage cost
375 // log call cost
----
total (2176 + 256 + 96 + 375) ~14% of sstore for 32 bytes
Most of the gas cost is actually spent on transaction data, not for the log operation itself

The reason that a log operation is cheap is because the log data isn’t really
stored in the blockchain. Logs, in principle, can be recalculated on the fly
as necessary.

Miners, in particular, can simply throw away the log data, because future
calculations can't access past logs anyway.

The network as a whole does not bear the cost of logs.
Only the API service nodes need to actually process, store, and index the logs.

So the cost structure of logging is just the minimal cost to prevent log spamming.

Extracted from stack-overflow:
   Q: """The price of ETH has gone from ~8 USD/ETH to ~90 ETH/USD in 6 months,
      but when I view transactions on the blockchain (example), I see that most
      people are still using the default gas price of 2e10 wei/gas. Shouldn't
      we be lowering the gas prices on our transactions to account for this
      price change?
      I have built a Dapp where low transaction fees are an important selling
      point. I intend to drop
      my gas price to 5e9 (a 75% reduction). Will my transactions still clear
      in a timely fashion?"""
   A: """Absolutely. Everyone should. There's a great site here that will help
     you understand gas and gas prices.
     It's called Ethereum Gas Station: http://ethgasstation.info/
      They just recently made this post which explains something they call the
     Safe Gas Price:
     https://medium.com/@ethgasstation/the-safe-low-gas-price-fb44fdc85b91"""


Ex: 1 Log per TX (NON-compacted):
TX       : 21000 gas/TX    * 1TX       = 21000
event    :   375 gas/LOG   * 1LOG      =   375
Topic    :   375 gas/topic * 3topic    =  1125
byte/logs: 8 gas/byte  * 150 bytes =  1240
                                          ------
                                 TOTAL     23740 gas   = 23740 gas º 0.000000032 Eth/gas º 300 Euros/Eth = 0.228  Eu

Ex: 5 Logs per TX (compacted):
TX       :  21000 gas/TX    * 1TX        = 21000
event    :    375 gas/LOG   * 1LOG       =   375
Topic    :    375 gas/topic * 3topic     =  1125
byte/logs:      8 gas/byte  * 1500 bytes = 12400
                                           ------
                                  TOTAL     34900 gas  = 34900 gas º 0.000000032 Eth/gas º 300 Euros/Eth = 0.33504 Eu (0.07 Eu 1Log)


Ex: Internal Storage: (Balance in block-chain):
TX       :      21000 gas/TX       * 1TX         = 21000
storage  :  20000 gas/32bytes  º 4º32 bytes      = 80000
evento   :        375 gas/LOG   * 1LOG           =   375
Topic    :        375 gas/topic * 3topic         =  1125
byte/logs:          8 gas/byte  * 150 bytes      =  1240
                                                  ------
                                      TOTAL       103740 gas  = 103740 gas º 0.000000032 Eth/gas º 300 Euros/Eth = 0.995904 Eu
gas price calc
Rº: WARN:º
- Extracted from @[https://medium.com/hackernoon/costs-of-a-real-world-ethereum-contract-2033511b3214]
  """(2017–08–23) The median gas price at the time of writing this article was,
  and continues to be, in the realm of 20 Gwei. This is far greater than the
  typical average and safe-low found on EthGasStation (4 and 0.5 Gwei respectively). 
  The median is so high because of bad gas-price defaults found in many wallets.
  I highly recommend using EthGasStation's average gas-price or lower in order
  to not pay high fees and to help drive down the market rate for gas-price."""

@[http://ethgasstation.info/calculator.php]
Gas (defined in the [Ethereum-Yellow-Paper]):
- virtual pricing mechanism for TXs (ether transfer and smart contracts controlled)
- Protect against Denial of Service attacks and resource-consumption attacks
  by compromised, malfunctioning or malicious nodes.
- EnterpriseEthereum provides additional tools to reduce security risks, such
  as more granular permissions for actions in a network or node-entrance
  firewalls and allowed/denied list of valid TX signers

Taking a reference ratio of 200€/ether:
TX gas price: 21000 gas/tx                 32bytes Contract storage: 20000 gas
┌──────────┼─────────────────┼────────┐   ┌──────────┼─────────────────┼────────┐
│ gasprice │ total gas price │ total €│   │ gasprice │ total gas price │ total €│
├──────────┼─────────────────┼────────┤   ├──────────┼─────────────────┼────────┤
│  1gwei   │ 21000 x  1gwei  │ 0,0042 │   │  1gwei   │ 21000 x  1gwei  │ 0,0040 │
│ 20gwei   │ 21000 x 20gwei  │ 0,0420 │   │ 20gwei   │ 21000 x 20gwei  │ 0,0400 │
└──────────┼─────────────────┼────────┘   └──────────┼─────────────────┼────────┘

For a transaction updating 64bytes (32bytes from debitor account to 32bytes
creditor account)
┌──────────┬───────────┐
│ gasprice │ total €   │
├──────────┼───────────┤
│  1gwei   │   0,0122  │
│ 20gwei   │   0,2440  │
└──────────┴───────────┘

ºLOGS-COST:º
┌────┬───────┬────────┬────────────┬────────────┐   375 gas for a LOG operation
│log │ numb. │ gas    │total       │     total €│ +   8 gas per log data-byte
│size│ topic │ price  │gas price   │  (200€/eth)│ + 375 gas for each topic.
├────┼───────┼────────┼────────────┼────────────┤
│1024│   3   │ 1gwei  │9692 x 1gwei│ 0,0019384 €│
│ 512│   3   │ 1gwei  │5596 x 1gwei│ 0,0011192 €│
│ 256│   1   │ 1gwei  │2798 x 1gwei│ 0,0005596 €│
│ 128│   0   │ 1gwei  │1399 x 1gwei│ 0,0002798 €│
├────┼───────┼────────┼────────────┼────────────┤
│    │       │ 20gwei │9692 x20gwei│ 0,0387680 €│
│ 512│   3   │  1gwei │5596 x 1gwei│ 0,0223840 €│
│ 256│   1   │  1gwei │2798 x 1gwei│ 0,0111920 €│
│ 128│   0   │  1gwei │1399 x 1gwei│ 0,0055960 €│
└────┴───────┴────────┴────────────┴────────────┘

(375 gas/LOG x 1LOG) + (8gas/byte x 1024byte) + (375 gas/topic * 3 topic) = 375 + 8192 + 1125 = 9692
(375 gas/LOG x 1LOG) + (8gas/byte x  512byte) + (375 gas/topic * 3 topic) = 375 + 4096 + 1125 = 5596
(375 gas/LOG x 1LOG) + (8gas/byte x  512byte) + (375 gas/topic * 1 topic) = 375 + 2048 +  375 = 2798
(375 gas/LOG x 1LOG) + (8gas/byte x  128byte) + (375 gas/topic * 0 topic) = 375 + 1024        = 1399
Calls vs TXs
Imagine a solidity code similar to:

  contract Voting {
    mapping (uint /*proposal */=˃ uint /*total votes*/) countMap;
    event totalForProposal(uint total)
    ...
    function vote(uint proposalID) 
    returns (uint total) {
       countMap[proposalID] = votes[proposalID]++;
       unit bºresultº = countMap[proposalID];
       emit totalForProposals(Bºresultº)
       return Bºresultº
    }
    ...
  }
This is function will modify the state of the blockchain
(it's not a "view"  or "pure" function in Solidity parlance)

Calling this function from "outside" the blockchain is done through
a criptographically signed transaction. The module (mobile wallet,
middleware,...) sending the signed transaction will wait indefinetely
while the TX is first propagated through the network to a mining node
, then mined (the miner executes the contract) and the TX receipt
received later on in a mined block).
The only way tthis external module has to fetch the result of the
function is through asynchronous eventsi,

This same function can be called in the mid of another transaction
when another method indirectly call it. This time, and that's why
the solidity code includes an "emit totalFroProposals..." as to
allow the module to be notified of the result.

- This function can also be part of a bigger execution path an called
in the mid of an started transaction. The EVM will already be executing
some method that in turn calls this "vote" function as part of a
normal program execution. When the "vote" function returns it has
access to the returned result since it has been placed on the EVM
stack. The emitted event is ignored (actually will be included in
the block after mining to be propagated back to any listening 
application).

Note also that we can have read-only functions ("view" or "pure"
in Solidity parlance"). In that case both an external module or
an internal function can fetch the returned value inmediatelly
(there is no TX propagation or mining and all the needed data
is local to the closest ethereum node -geth, parity,...-). 
The javascript web3js (or java web3j or ...) 
In the case of the external module through an RPC call, and in
the case of an internal EVM function through the (much faster)
EVM stack. 


State transition fun
APPLY (S, TX) → S'  ← S : initial global state
                    ← S': final   global state
 can be defined as follows:
- Check if incomming TX is well-formed (right number of values),
  signature is valid, and the nonce matches the nonce in the
  sender's account.  Return an error otherwise.
- Calculate the transaction fee as STAR_GAS * GAS_PRICE, and
  determine the sending address from the signature. Subtract the
  fee from the sender's account balance and increment the
  sender's nonce. If sender's balance ˂ fee, return an error.
- Initialize GAS = STARTGAS, and take off a certain quantity
  of gas per byte to pay for the bytes in the transaction.
- Transfer the TX value from the sender's account to the
  receiving account.  If the receiving account does not yet
  exist, create if. If the receiving account is a contract,
  run the contract's code either to completion or until the
  execution runs out of gas.
- If the value transfer failed because the sender did not have
  enough money, or the code execution ran out of gas, revert
  all state changes except the payment of the fees, and add
  the fees to the miner's account
- Otherwise, refund the fees for all remaining gas to
  the sender, and send the fees paid for gas consumed to the
  miner.
Offline/Online
TX signing
    OFFLINE TX SIGNING (RECOMENDED)           |    "ON-LINE" TX SIGNING (LESS SECURE, DISCOURAGED)
                                              |
The "raw" TX must be signed first             | - An Ethereum node (geth, parity,...) will be used.
by an offline (js,python,hardware wallet,...) | - It forces to have the wallet on the client node and
client using a private key ("wallet")         |   unlock the account. Unless the wallet is hardware
with or without connection to any ethereum    |   secured is usually less safe than client signature
network node.                                 |   (but offline clients can also be insecure or
The signed TX is then sent to the network.    |   hacked)
About 24K
Contract Size
[https://ethereum-magicians.org/t/removing-or-increasing-the-contract-size-limit/3045]

BºNote:º Pantheon (maybe others) allows to tune max.contract size 
         in consortium / private networks.

RºWARN: I admit that I haven’t kept up with the 2.0 specs and all my statements are º
       ºbased on eth 1.x. º

(See original link for -very- detailed info)

- EIP #170 22 establish a max contract size of 24KB to solve the problem:
  “When a contract is called, even though the call takes a constant amount of gas,
  the call can trigger O(n) cost in terms of reading the code from disk, preprocessing
  the code for VM execution, and also adding O(n) data to the Merkle proof for the
  block’s proof-of-validity”.

ºCurrent Solutionº
- Delegate call proxy patterns and Libraries:
  Using delegate calls, you can store the code of your smart contract in parts
  in different contracts and have a "dispatcher" contract that calls the actual
  contract using delegate calls.
  - Please refer to ZeppelinOS’s upgradability contracts 8 and EIP #1538 3.

  -ºLimitationsº
    - extra unnecessary code.
    - Proxy patterns add another attack vector.
    - Proxy patterns make calls to contracts a lot more
      expensive as the Proxy has to copy the parameters make an
      external delegate call every time.
    - Proxy patterns like EIP 1538 also make inter-logic contract call 
      a lot more expensive. 
       external call -> proxy    -> contract -> contract2 
                        contract    call 
    - hurt readability for the end user:
      - The actual contract code/ABI of the proxy is different from the one 
        we need to access the contract behind the proxy. Like it or not but
        most people can barely use the read/write features in etherscan, 
       they can't load a custom ABI and make web3 calls.
    - Proxies make smart contract development slightly more complex.
    - Proxies make it harder to verify the actual code and hence reduce trust.
    - Loading a large contract will be fast-sequential read while loading 
      multiple small ones will be slow-random read.

ºPossible Solutionsº
- Increase contract size limit to 32,768 (2**15) proposed by @gavofyork in 
  EIP 170 discussion 8. (50% code increase)
- If required, relevant opcodes like CALL can have their cost increased 
  by a bit through EIP #1838 4.
- Allow infinite contract size by Implementing paging of contract code
  as suggested by @SergioDemianLerner in EIP #170 discussion 3.
  "Make contracts a vector of 24 Kbytes pages". 
  - first page is loaded for free when a CALL is received while jumping
    or running into another page pays a fee (500 gas) because the page
    must be fetched from disk.
- Allow infinite contract size and make the cost of OPCODES like CALL
  dynamic to allow for this change. Code size will still be limited by
  block gas limit. This is a moderate difficulty change but makes a lot 
  of sense IMO. More on this later:
  - In detail:
    - ethereum account   (array in state trie)
      ---------------- 
       nonce 
       balance 
       storageRoot 
       codeHash 
      ºcodeSize     ←-- New proposed additionº
       ^^^^^^^^         
      - Whenever a new contract is deployed, its size is stored here
      - If a contract is destructed, codeSize is reseted.

    - CALL, DELEGATECALL, CALLCODE , ... opcodes should charge additional 
      X(3?) gas per extra word if the contract code size is greater than 24KB.
  - Rationale
    The only reason why the contract size was limited was to prevent people
    from exploiting the fixed costs. We can overcome this by making the 
    costs variable. The codeSize element will help in calculating call cost 
    before reading the whole contract and eventually throwing OOG. 
    - Merkle proofs will also be generated at a fixed cost as we won't have
      to load whole contracts from disk first. The codeSize should be enough
      for generating Merkle proofs of calls that are going to be OOG due
      to contract size.
  - Backwards Compatibility 
    - All existing accounts have less than 24KB of code, so no extra cost
      has to be charged from calls being sent to them.

Tagging @karalabe for his thoughts as he is working on reducing state size.
Ether.Addresses
Issues
REF: @[https://ethereum.stackexchange.com/questions/267/why-dont-ethereum-addresses-have-checksums]
Initial Ethereum design didn't have support for address checksum.
thus, a single mistyped digit could make sending to an invalid 
address (loosing all the money).

Q: Was it an oversight that was overlooked by the designers?
A: the raw hexadecimal string ussually called "Ethereum address" 
   wasn't even intended to be the standard way of representing such information.
   containing no checksums. On top of it software can be written 
   creating an encoding and string in base 58 with built-in version number
   and checksum, 100% interoperable by silently decoding the new 

NOTE: always include "0x" prefix in front of raw addresses

ICAP Addresses
IBAM Compatible
@[https://github.com/ethereum/wiki/wiki/Inter-exchange-Client-Address-Protocol-(ICAP)]
- ICAP: Inter Exchange Client Address Protocol (ICAP) 
- compatible with IBAN account formatting.
 
It looks like: "XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS". 

- (it uses a wider range of alphanumeric characters to save
  space and includes a checksum. similar to Bitcoin) 

- ICAP is a fully valid International Bank Account Number (or IBAN).

- It doesn't use hexadecimal addresses. BY the help of ENS 
  it can just use an actual human-readable-string to end up
  with something like "XE81ETHXREGJEFFCOLEMAN".
                       ^^^^^^^^^^^^^^^^^^^^^^
                   "XE81 ETH XREG JEFF COLEMAN"
                  (It still matches bank formats)

 Update 2016-02: Vitalik ºtransitionalº checksumming: 
  - provides some additional protection against accidental errors 
  while remaining backwards compatible with wallets that doesn't support 
  the checksum (and will ignore the case differences). 

  - Ex: Input address '0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826'
  
    Output checksumed:'0xCd2a3d9f938e13Cd947eC05ABC7fe734df8DD826'
                         ^             ^     ^  ^^^         ^^
                         └──────────────────────────────────────┘
            letters are in the same corresponding place as a "1" bit
            in the raw binary keccack-256 hash of the address bytes
            are capitalised. Numbers are unchanged.
 

Update: EIP55 introduces checksum in Ethereum addresses. (Still optional
        but widely adopted -Metamask,...-)


Ethereum Name Service
@[https://ens.domains/]
"""No more long addresses: ENS eliminates the need to copy - and worse,
   type - long hexadecimal addresses ...
   you'll be able to:
   - send money to 'aardvark.eth' instead of '0x4cbe58c50480...',
   - interact with your favorite contract at 'mycontract.eth'
   - visit a Swarm-hosted site at 'swarmsite.eth'. """

ºExt. Linksº
- EIP137 - Ethereum Name Service
- EIP137 issues
- EIP162 - Initial ENS Registrar Specification
- ethereum-ens Javascript library
  Nick’s talk on ENS at DevCon 2: https://www.youtube.com/watch?v=pLDDbCZXvTE
- DevCon 2 talk slides
- https://registrar.ens.domains
- ENS User Guide,
- Geth implementation

GOAL: resolve human-readable names to Ethereum addresses, Swarm/IPFS hashes, ....
      provide also metadata about names (contracts ABIs, whois info,...)
- ENS operates on a system of Oºdot-separated hierarchial names called domainsº,
  with the owner of a domain having full control over the distribution of subdomains.

- Top-level domains (.eth, .test,...) owned by 'registrars' smart contracts
  Anyone may, by following the rules imposed by these registrar contracts,
  obtain ownership of a second-level domain for their own use.

- Secure: ENS is built on smart contracts on the Ethereum blockchain, meaning
  it doesn't suffer from the insecurity of the DNS system.  You can be confident
  names you enter work the way their owner intended.

- Truly Distributed: ENS operates in a distributed fashion for both its infrastructure
  and governance. Anyone can register a .eth domain name for themselves by participating
  in an auction process, mediated by the blockchain.

ºTERMINOLOGYº
  - domain     : complete, human-readable form of a name; eg, ‘vitalik.wallet.eth’
  - label      : a single component of a domain; eg, ‘vitalik’, ‘wallet’, or ‘eth’
  - label hash : keccak-256(label) eg, keccak256(‘eth’) =
                 0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0
  - node       : namehash function output used to uniquely identify a name in ENS


ºEx. JS Client code to registerº REF

| var name = "MyPersonalDemocracy"
| registrar.reserve.sendTransaction(name, {from: eth.accounts[0]})
| var democracy = eth.contract(daoCompiled.Democracy.info.abiDefinition).
|                 at(democracy.address);
| democracy.setup.sendTransaction(registrar.addr("MyFirstCoin"),{from:eth.accounts[0]})
|
| (Wait for the previous transactions to be picked up and then)
|
| registrar.setAddress.sendTransaction(name, democracy.address, true,{from: eth.accounts[0]});

Architecture
DOMAIN            | REGISTRY CONTRACT                  | RESOLVER(S) INTERFACE
------            | -----------------                  | ---------------------
- owner (address) | - owned (sub)domains list          | translate name → address
- resolver        | ----------------                   +-------------------------
- time-to-live    | + issues subdomains to users  *1
  for all records |   following logic in contract *1   | RECORD:
                  | + Set resolver+TTL for domain *1   | -------
                  | + Transfer ownership               | - type: (Ethereum address, Swarm content hash, ...)
                  | *1 Only owner of affected domain   |          New record types may be defined via EIP
                                                       |          with no need to make changes to the registry or resolvers
                                                       |
                                                       | - Namehash: 32-byte hash of name (compaq storage+privacy)
                                                       |             defined recursively to preserve the hierarchal nature
                                                       | ----------
                                                       | - Iface method/s to be implemented by resolver
                                                       |    in order to provide records of that kind.

ºMainNet/... Deploymentsº
General-purpose resolver implementations are offered for users whose requirements are straightforward,
such as serving an infrequently changed address for a name.

  MAINNET DEPLOYMENT: 0x314159265dd8dbb310642f98f50c066173c1259b
                      users may register names under the eth TLD using an auction based registrar.
  ROPSTEN
  TESTNET DEPLOYMENT: 0x112234455c3a32fd11230c42e7bccd4a84e02010
                      users may register names under two top level domains:
                      .eth , auction based
                      .test, allows anyone to claim an unused name for test purposes expiring after 28 days
  RINKEBY
  TESTNET DEPLOYMENT: 0xe7410170f87102df0055eb195163a03b7f2bff4a
                      .test supported
Solidity
Learn X in Y min

@[https://learnxinyminutes.com/docs/solidity/]
Where X=Solidity
- statically typed.

- OOP: a contract ("class")  contains state variables, private/public functions

-ºEvent-stream oriented:º
  - Clients "outside" the ethereum network send 
    ºsigned TXsº to the network.ºEventuallyº those TXs will be
    accepted ("mined") by the consensus and the modified state
    eventually propagated back with the propagation on new
    accepted ("mined") blocks. 
    Each TXs can also create new inmutable logs that are also
    propagated back with the new mined block propagation.

  First Important different when compared with standard languages:
  - A function invoqued "outside" the network (from a new 
    signed TX pending to be mined) can return values, but
    those values will be mostly ignored (except, maybe by the
    debugger during the development phase). Events are used
    to inform the client about application-layer data.
    (Some low level-EVM data can be directly extracted from the
    TX receipt, like the gas spent, hash, ...).

// Allows deposits, withdrawals, and balance checks

// simple_bank.sol (note .sol extension)
/* **** START EXAMPLE **** */


// ** END EXAMPLE **


// Now, the basics of Solidity

// 1. DATA TYPES AND ASSOCIATED METHODS
// uint used for currency amount (there are no doubles
//  or floats) and for dates (in unix time)
uint x;

// 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 explicit
uint constant VERSION_ID = 0x123A1; // A hex constant
// with 'constant', compiler replaces each occurrence with actual value

// All state variables (those outside a function)
// are by default 'internal' and accessible inside contract
// and in all contracts that inherit ONLY
// Need to explicitly set to 'public' to allow external contracts to access
int256 public a = 8;

// For int and uint, can explicitly set space in steps of 8 up to 256
// e.g., int8, int16, int24
uint8 b;
int64 c;
uint248 e;

// Be careful that you don't overflow, and protect against attacks that do
// For example, for an addition, you'd do:
uint256 c = a + b;
assert(c >= a); // assert tests for internal invariants; require is used for user inputs
// For more examples of common arithmetic issues, see Zeppelin's SafeMath library
// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol


// No random functions built in, use other contracts for randomness

// Type casting
int x = int(b);

bool b = true; // or do 'var b = true;' for inferred typing

// Addresses - holds 20 byte/160 bit Ethereum addresses
// No arithmetic allowed
address public owner;

// Types of accounts:
// Contract account: address set on create (func of creator address, num transactions sent)
// External Account: (person/external entity): address created from public key

// Add 'public' field to indicate publicly/externally accessible
// a getter is automatically created, but NOT a setter

// All addresses can be sent ether
owner.transfer(SOME_BALANCE); // fails and reverts on failure

// Can also do a lower level .send call, which returns a false if it failed
if (owner.send) {} // REMEMBER: wrap send in 'if', as contract addresses have
// functions executed on send and these can fail
// Also, make sure to deduct balances BEFORE attempting a send, as there is a risk of a recursive
// call that can drain the contract

// Can check balance
owner.balance; // the balance of the owner (user or contract)


// Bytes available from 1 to 32
byte a; // byte is same as bytes1
bytes2 b;
bytes32 c;

// Dynamically sized bytes
bytes m; // A special array, same as byte[] array (but packed tightly)
// More expensive than byte1-byte32, so use those when possible

// same as bytes, but does not allow length or index access (for now)
string n = "hello"; // stored in UTF8, note double quotes, not single
// string utility functions to be added in future
// prefer bytes32/bytes, as UTF8 uses more storage

// Type inference
// var does inferred typing based on first assignment,
// can't be used in functions parameters
var a = true;
// use carefully, inference may provide wrong type
// e.g., an int8, when a counter needs to be int16

// var can be used to assign function to variable
function a(uint x) returns (uint) {
    return x * 2;
}
var f = a;
f(22); // call

// by default, all values are set to 0 on instantiation

// Delete can be called on most types
// (does NOT destroy value, but sets value to 0, the initial value)
uint x = 5;


// Destructuring/Tuples
(x, y) = (2, 7); // assign/swap multiple values


// 2. DATA STRUCTURES
// Arrays
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
names.length = 1; // lengths can be set (for dynamic arrays in storage only)

// multidimensional array
uint x[][5]; // arr with 5 dynamic array elements (opp order of most languages)

// Dictionaries (any type to any other type)
mapping (string => uint) public balances;
balances["charles"] = 1;
// balances["ada"] result is 0, all non-set key values return zeroes
// 'public' allows following from another contract
contractName.balances("charles"); // returns 1
// 'public' created a getter (but not setter) like the following:
function balances(string _account) returns (uint balance) {
    return balances[_account];
}

// Nested mappings
mapping (address => mapping (address => uint)) public custodians;

// To delete
delete balances["John"];
delete balances; // sets all elements to 0

// Unlike other languages, CANNOT iterate through all elements in
// mapping, without knowing source keys - can build data structure
// on top to do this

// Structs
struct Bank {
    address owner;
    uint balance;
}
Bank b = Bank({
    owner: msg.sender,
    balance: 5
});
// or
Bank c = Bank(msg.sender, 5);

c.balance = 5; // set to new value
delete b;
// sets to initial value, set all variables in struct to 0, except mappings

// Enums
enum State { Created, Locked, Inactive }; // often used for state machine
State public state; // Declare variable from enum
state = State.Created;
// enums can be explicitly converted to ints
uint createdState = uint(State.Created); //  0

// Data locations: Memory vs. storage vs. calldata - 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 func params
// stack holds small local variables

// for most types, can explicitly set which data location to use


// 3. Simple operators
// Comparisons, bit operators and arithmetic operators are provided
// exponentiation: **
// exclusive or: ^
// bitwise negation: ~


// 4. Global Variables of note
// ** this **
this; // address of contract
// often used at end of contract life to transfer remaining balance to party
this.balance;
this.someFunction(); // calls func externally via call, not via internal jump

// ** msg - Current message received by the contract ** **
msg.sender; // address of sender
msg.value; // amount of ether provided to this contract in wei, the function should be marked "payable"
msg.data; // bytes, complete call data
msg.gas; // remaining gas

// ** tx - This transaction **
tx.origin; // address of sender of the transaction
tx.gasprice; // gas price of the transaction

// ** block - Information about current block **
now; // current time (approximately), alias for block.timestamp (uses Unix time)
// Note that this can be manipulated by miners, so use carefully

block.number; // current block number
block.difficulty; // current block difficulty
block.blockhash(1); // returns bytes32, only works for most recent 256 blocks
block.gasLimit();

// ** storage - Persistent storage hash **
storage['abc'] = 'def'; // maps 256 bit words to 256 bit words


// 4. FUNCTIONS AND MORE
// A. Functions
// Simple function
function increment(uint x) returns (uint) {
    x += 1;
    return x;
}

// Functions can return many arguments, and by specifying returned arguments
// name don't need to explicitly return
function increment(uint x, uint y) returns (uint x, uint y) {
    x += 1;
    y += 1;
}
// Call previous functon
uint (a,b) = increment(1,1);

// 'view' (alias for 'constant')
// indicates that function does not/cannot change persistent vars
// View function execute locally, not on blockchain
// Noted: constant keyword will soon be deprecated.
uint y = 1;

function increment(uint x) view returns (uint x) {
    x += 1;
    y += 1; // this line would fail
    // y is a state variable, and can't be changed in a view function
}

// 'pure' is more strict than 'view' or 'constant', and does not
// even allow reading of state vars
// The exact rules are more complicated, so see more about
// view/pure:
// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions

// 'Function Visibility specifiers'
// These can be placed where 'view' is, including:
// public - visible externally and internally (default for function)
// external - only visible externally (including a call made with this.)
// private - only visible in the current contract
// internal - only visible in current contract, and those deriving from it

// Generally, a good idea to mark each function explicitly

// Functions hoisted - and can assign a function to a variable
function a() {
    var z = b;
    b();
}

function b() {

}

// All functions that receive ether must be marked 'payable'
function depositEther() public payable {
    balances[msg.sender] += msg.value;
}


// Prefer loops to recursion (max call stack depth is 1024)
// Also, don't setup loops that you haven't bounded,
// as this can hit the gas limit

// B. Events
// Events are notify external parties; easy to search and
// access events from outside blockchain (with lightweight clients)
// typically declare after contract parameters

// Typically, capitalized - and add Log in front to be explicit and prevent confusion
// with a function call

// Declare
event LogSent(address indexed from, address indexed to, uint amount); // note capital first letter

// Call
LogSent(from, to, amount);

/**

For an external party (a contract or external entity), to watch using
the Web3 Javascript library:

// The following is Javascript code, not Solidity code
Coin.LogSent().watch({}, '', function(error, result) {
    if (!error) {
        console.log("Coin transfer: " + result.args.amount +
            " coins were sent from " + result.args.from +
            " to " + result.args.to + ".");
        console.log("Balances now:\n" +
            "Sender: " + Coin.balances.call(result.args.from) +
            "Receiver: " + Coin.balances.call(result.args.to));
    }
}
**/

// Common paradigm for one contract to depend on another (e.g., a
// contract that depends on current exchange rate provided by another)

// C. Modifiers
// Modifiers validate inputs to functions such as minimal balance or user auth;
// similar to guard clause in other languages

// '_' (underscore) often included as last line in body, and indicates
// function being called should be placed there
modifier onlyAfter(uint _time) { require (now >= _time); _; }
modifier onlyOwner { require(msg.sender == owner) _; }
// commonly used with state machines
modifier onlyIfStateA (State currState) { require(currState == State.A) _; }

// Append right after function declaration
function changeOwner(newOwner)
onlyAfter(someTime)
onlyOwner()
onlyIfState(State.A)
{
    owner = newOwner;
}

// underscore can be included before end of body,
// but explicitly returning will skip, so use carefully
modifier checkValue(uint amount) {
    _;
    if (msg.value > amount) {
        uint amountToRefund = amount - msg.value;
        msg.sender.transfer(amountToRefund);
    }
}


// 6. BRANCHING AND LOOPS

// All basic logic blocks work - including if/else, for, while, break, continue
// return - but no switch

// Syntax same as javascript, but no type conversion from non-boolean
// to boolean (comparison operators must be used to get the boolean val)

// For loops that are determined by user behavior, be careful - as contracts have a maximal
// amount of gas for a block of code - and will fail if that is exceeded
// For example:
for(uint x = 0; x < refundAddressList.length; x++) {
    refundAddressList[x].transfer(SOME_AMOUNT);
}

// Two errors above:
// 1. A failure on transfer stops the loop from completing, tying up money
// 2. This loop could be arbitrarily long (based on the amount of users who need refunds), and
// therefore may always fail as it exceeds the max gas for a block
// Instead, you should let people withdraw individually from their subaccount, and mark withdrawn
// e.g., favor pull payments over push payments


// 7. OBJECTS/CONTRACTS

// A. Calling external contract
contract InfoFeed {
    function info() payable returns (uint ret)  { return 42; }
}

contract Consumer {
    InfoFeed feed; // points to contract on blockchain

    // Set feed to existing contract instance
    function setFeed(address addr) {
        // automatically cast, be careful; constructor is not called
        feed = InfoFeed(addr);
    }

    // Set feed to new instance of contract
    function createNewFeed() {
        feed = new InfoFeed(); // new instance created; constructor called
    }

    function callFeed() {
        // final parentheses call contract, can optionally add
        // custom ether value or gas
        feed.info.value(10).gas(800)();
    }
}

// B. Inheritance

// Order matters, last inherited contract (i.e., 'def') can override parts of
// previously inherited contracts
contract MyContract is abc, def("a custom argument to def") {

// Override function
    function z() {
        if (msg.sender == owner) {
            def.z(); // call overridden function from def
            super.z(); // call immediate parent overridden function
        }
    }
}

// abstract function
function someAbstractFunction(uint x);
// cannot be compiled, so used in base/abstract contracts
// that are then implemented

// C. Import

import "filename";
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";


// 8. OTHER KEYWORDS

// A. Selfdestruct
// selfdestruct current contract, sending funds to address (often creator)
selfdestruct(SOME_ADDRESS);

// removes storage/code from current/future blocks
// helps thin clients, but previous data persists in blockchain

// Common pattern, lets owner end the contract and receive remaining funds
function remove() {
    if(msg.sender == creator) { // Only let the contract creator do this
        selfdestruct(creator); // Makes contract inactive, returns funds
    }
}

// May want to deactivate contract manually, rather than selfdestruct
// (ether sent to selfdestructed contract is lost)


// 9. CONTRACT DESIGN NOTES

// A. Obfuscation
// All variables are publicly viewable on blockchain, so anything
// that is private needs to be obfuscated (e.g., hashed w/secret)

// Steps: 1. Commit to something, 2. Reveal commitment
keccak256("some_bid_amount", "some secret"); // commit

// call contract's reveal function in the future
// showing bid plus secret that hashes to SHA3
reveal(100, "mySecret");

// B. Storage optimization
// Writing to blockchain can be expensive, as data stored forever; encourages
// smart ways to use memory (eventually, compilation will be better, but for now
// benefits to planning data structures - and storing min amount in blockchain)

// Cost can often be high for items like multidimensional arrays
// (cost is for storing data - not declaring unfilled variables)

// C. Data access in blockchain
// Cannot restrict human or computer from reading contents of
// transaction or transaction's state

// While 'private' prevents other *contracts* from reading data
// directly - any other party can still read data in blockchain

// All data to start of time is stored in blockchain, so
// anyone can observe all previous data and changes

// D. Cron Job
// Contracts must be manually called to handle time-based scheduling; can create external
// code to regularly ping, or provide incentives (ether) for others to

// E. Observer Pattern
// An Observer Pattern lets you register as a subscriber and
// register a function which is called by the oracle (note, the oracle pays
// for this action to be run)
// Some similarities to subscription in Pub/sub

// This is an abstract contract, both client and server classes import
// the client should implement
contract SomeOracleCallback {
    function oracleCallback(int _value, uint _time, bytes32 info) external;
}

contract SomeOracle {
    SomeOracleCallback[] callbacks; // array of all subscribers

    // Register subscriber
    function addSubscriber(SomeOracleCallback a) {
        callbacks.push(a);
    }

    function notify(value, time, info) private {
        for(uint i = 0;i < callbacks.length; i++) {
            // all called subscribers must implement the oracleCallback
            callbacks[i].oracleCallback(value, time, info);
        }
    }

    function doSomething() public {
        // Code to do something

        // Notify all subscribers
        notify(_value, _time, _info);
    }
}

// Now, your client contract can addSubscriber by importing SomeOracleCallback
// and registering with Some Oracle

// F. State machines
// see example below for State enum and inState modifier


// *** EXAMPLE: A crowdfunding example (broadly similar to Kickstarter) ***
// ** START EXAMPLE **

// CrowdFunder.sol
pragma solidity ^0.4.19;

/// @title CrowdFunder
/// @author nemild
contract CrowdFunder {
    // Variables set on create by creator
    address public creator;
    address public fundRecipient; // creator may be different than recipient
    uint public minimumToRaise; // required to tip, else everyone gets refund
    string campaignUrl;
    byte constant version = 1;

    // Data structures
    enum State {
        Fundraising,
        ExpiredRefund,
        Successful
    }
    struct Contribution {
        uint amount;
        address contributor;
    }

    // State variables
    State public state = State.Fundraising; // initialize on create
    uint public totalRaised;
    uint public raiseBy;
    uint public completeAt;
    Contribution[] contributions;

    event LogFundingReceived(address addr, uint amount, uint currentTotal);
    event LogWinnerPaid(address winnerAddress);

    modifier inState(State _state) {
        require(state == _state);
        _;
    }

    modifier isCreator() {
        require(msg.sender == creator);
        _;
    }

    // Wait 24 weeks after final contract state before allowing contract destruction
    modifier atEndOfLifecycle() {
    require(((state == State.ExpiredRefund || state == State.Successful) &&
        completeAt + 24 weeks < now));
        _;
    }

    function CrowdFunder(
        uint timeInHoursForFundraising,
        string _campaignUrl,
        address _fundRecipient,
        uint _minimumToRaise)
        public
    {
        creator = msg.sender;
        fundRecipient = _fundRecipient;
        campaignUrl = _campaignUrl;
        minimumToRaise = _minimumToRaise;
        raiseBy = now + (timeInHoursForFundraising * 1 hours);
    }

    function contribute()
    public
    payable
    inState(State.Fundraising)
    returns(uint256 id)
    {
        contributions.push(
            Contribution({
                amount: msg.value,
                contributor: msg.sender
            }) // use array, so can iterate
        );
        totalRaised += msg.value;

        LogFundingReceived(msg.sender, msg.value, totalRaised);

        checkIfFundingCompleteOrExpired();
        return contributions.length - 1; // return id
    }

    function checkIfFundingCompleteOrExpired()
    public
    {
        if (totalRaised > minimumToRaise) {
            state = State.Successful;
            payOut();

            // could incentivize sender who initiated state change here
        } else if ( now > raiseBy )  {
            state = State.ExpiredRefund; // backers can now collect refunds by calling getRefund(id)
        }
        completeAt = now;
    }

    function payOut()
    public
    inState(State.Successful)
    {
        fundRecipient.transfer(this.balance);
        LogWinnerPaid(fundRecipient);
    }

    function getRefund(uint256 id)
    inState(State.ExpiredRefund)
    public
    returns(bool)
    {
        require(contributions.length > id && id >= 0 && contributions[id].amount != 0 );

        uint256 amountToRefund = contributions[id].amount;
        contributions[id].amount = 0;

        contributions[id].contributor.transfer(amountToRefund);

        return true;
    }

    function removeContract()
    public
    isCreator()
    atEndOfLifecycle()
    {
        selfdestruct(msg.sender);
        // creator gets all money that hasn't be claimed
    }
}
// ** END EXAMPLE **

// 10. OTHER NATIVE FUNCTIONS

// Currency units
// Currency is defined using wei, smallest unit of Ether
uint minAmount = 1 wei;
uint a = 1 finney; // 1 ether == 1000 finney
// Other units, see: http://ether.fund/tool/converter

// Time units
1 == 1 second
1 minutes == 60 seconds

// Can multiply a variable times unit, as units are not stored in a variable
uint x = 5;
(x * 1 days); // 5 days

// Careful about leap seconds/years with equality statements for time
// (instead, prefer greater than/less than)

// Cryptography
// All strings passed are concatenated before hash action
sha3("ab", "cd");
ripemd160("abc");
sha256("def");

// 11. SECURITY

// Bugs can be disastrous in Ethereum contracts - and even popular patterns in Solidity,
// may be found to be antipatterns

// See security links at the end of this doc

// 12. LOW LEVEL FUNCTIONS
// call - low level, not often used, does not provide type safety
successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2');

// callcode - Code at target address executed in *context* of calling contract
// provides library functionality
someContractAddress.callcode('function_name');


// 13. STYLE NOTES
// Based on Python's PEP8 style guide
// Full Style guide: http://solidity.readthedocs.io/en/develop/style-guide.html

// Quick summary:
// 4 spaces for indentation
// Two lines separate contract declarations (and other top level declarations)
// Avoid extraneous spaces in parentheses
// Can omit curly braces for one line statement (if, for, etc)
// else should be placed on own line


// 14. NATSPEC COMMENTS
// used for documentation, commenting, and external UIs

// Contract natspec - always above contract definition
/// @title Contract title
/// @author Author name

// Function natspec
/// @notice information about what function does; shown when function to execute
/// @dev Function documentation for developer

// Function parameter/return value natspec
/// @param someParam Some description of what the param does
/// @return Description of the return value

Additional resources

    Solidity Docs
    Smart Contract Best Practices
    Superblocks Lab - Browser based IDE for Solidity
    EthFiddle - The JsFiddle for Solidity
    Browser-based Solidity Editor
    Gitter Solidity Chat room
    Modular design strategies for Ethereum Contracts

Important libraries

    Zeppelin: Libraries that provide common contract patterns (crowdfuding, safemath, etc)

Sample contracts

    Dapp Bin
    Solidity Baby Step Contracts
    ConsenSys Contracts
    State of Dapps

Security

    Thinking About Smart Contract Security
    Smart Contract Security
    Hacking Distributed Blog

Style

    Solidity Style Guide: Ethereum’s style guide is heavily derived from Python’s PEP 8 style guide.

Editors

    Emacs Solidity Mode
    Vim Solidity
    Editor Snippets (Ultisnips format)

Future To Dos

    New keywords: protected, inheritable
    List of common design patterns (throttling, RNG, version upgrade)
    Common security anti patterns

Feel free to send a pull request with any edits - or email nemild -/at-/ gmail

External Links
@[https://remix.ethereum.org/#]   Online IDE
@[https://solidity.readthedocs.io/en/latest/solidity-in-depth.html]
@[https://solidity.readthedocs.io/en/develop/]
@[https://github.com/ethereum/solidity/blob/develop/docs/grammar.txt] EBNF Grammar Summary
@[https://ethfiddle.com/]
@[https://github.com/ConsenSys/smart-contract-best-practices']
GLOBALS
ºGLOBAL METHODS:º
block.blockhash(uint blockNumber)
  returns (bytes32):
  hash of the given block - only works for 256 most
  recent blocks excluding current

ºGLOBAL VARS:º
Oºmsg.sender (address)    : sender of the message (current call)º
Oºtx.origin (address)     : sender of the transaction           º
Oº                          (full call chain)                   º
msg.sender vs tx.origin:
@[https://ethereum.stackexchange.com/questions/1891/whats-the-difference-between-msg-sender-and-tx-origin]
"""
- With msg.sender the owner can be a contract.
- With tx.origin the owner can never be a contract.
  In a simple call chain A→B→C→D,  inside D msg.sender will be C, and tx.origin will be A.

- msg.sender is preferred for the flexibility it provides.
  Furthermore, for Serenity, even though it's a while out, Vitalik
  recommends avoiding tx.origin: How do I make my DAPP "Serenity-Proof?"
- Carefully consider if you really ever need to use tx.origin.
  Remember, you may not be the only user of your contract.
  Other people may want to use your contract and want to interact
   with it via a contract they've been written.

"""


block.coinbase (address): current block miner’s address
block.difficulty (uint) : current block difficulty
block.gaslimit (uint)   : current block gaslimit
block.number (uint)     : current block number
block.timestamp (uint)  : current block timestamp

https://ethereum.stackexchange.com/questions/7853/is-the-block-timestamp-value-in-solidity-seconds-or-milliseconds
msg.data (bytes)        : complete calldata
msg.gas (uint)          : remaining gas
msg.sig (bytes4)        : first four bytes of the calldata
                          (i.e. function identifier)
msg.value (uint)        : number of wei sent with the message
now (uint)              : current block timestamp
                          (alias for block.timestamp)
tx.gasprice (uint)      : gas price of the transaction



ºGLOBAL Math.&Crypto Functsº
addmod(uint x, uint y, uint k)
  returns (uint): /* compute (x + y) % k */
mulmod(uint x, uint y, uint k)
  returns (uint): /* compute (x * y) % k */
keccak256(...)
  returns (bytes32): compute Ethereum-SHA-3 hash
                of the (tightly packed) arguments
  - See also keccak256 in web3js
sha3(...)
  returns (bytes32): alias to keccak256()
sha256(...)
  returns (bytes32): compute SHA-256 hash of the
                      (tightly packed) arguments
ripemd160(...)
  returns (bytes20): compute RIPEMD-160 hash of
  the (tightly packed) arguments
ecrecover
  (bytes32 hash, uint8 v, bytes32 r, bytes32 s)
  returns (address):
    recover the address associated with the public key
    from elliptic curve signature or return zero on error
Strings
CAN NOTs:                               |  CANs:
 - Can NOT be concatenated.             |  - Can be used as keys for mappings

ºComparing strings:º
   sha3(      "string1" ) == sha3("string2")  ← sha3("...") translates to sha3(bytes("..."))
   ^^^^
   remember: sha3 is an alias for keccak256

ºcheck if string is empty:º
Check white-space paddings
bool stringNotEmpty = bytes(myTestedString).length > 0; // alt 1, check underlying bytes array length
                                            ^^^^^^^
                                length implemented for
                                bytes, not (yet) for string

bool stringNotEmpty = sha3 (myTestedString) != sha3("")    // alt 2, check sha3

ºuint256 ←→ Strings:º
    // https://ethereum.stackexchange.com/questions/6591/conversion-of-uint-to-string
    function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
      if (_i == 0) {    return "0"; }
        uint j = _i;
        uint len;
        while (j != 0) { // calculate decimals
            len++;
            j /= 10;
        }
       ºbytes memory bstr = new bytes(len);º
        uint k = len - 1;
        while (_i != 0) {
            bstr[k--] = byte(uint8(48 + _i % 10));
            _i /= 10;
        }
        return string(bstr);
    }
ºbytes32 ←→ Strings:º
code@stackoverflow  doesn't look to work

ºSTRING LIBRARIES:º
@[https://github.com/Arachnid/solidity-stringutils]

@[https://github.com/blockapps/blockapps-sol/blob/master/util/contracts/Util.sol]
Date/Time
// DateTime is stored as uint

// "Oºnowº" returns the (uint) current block timestamp (alias for block.timestamp)

uint QºtimeOutWindowº = Qº_inputTimeOutWindowº Oºº 1 minutes || 30 days*;
                                                   ^^^^^^^^^^^^^^^^^^^^^^
                                                   1 minutes == 60 seconds
                                                   1 hours == 60 minutes   
                                                   1 days == 24 hours      
                                                   1 weeks == 7 days       

function myTimeOutDependentFunction(...) returns (...) {
    ...
    if (Oºnowº ˃ (Qºtime_origin + timeOutWindowº) throw;
    ... Do something ...
}
FUNCTIONS
ºmodifiersº (Deprecated?)
Gºmodifier inStateº(State _state)    { if (state != _state) throw;  _;  }
Gºmodifier requireº(bool _condition) { if (!_condition) throw; _;       }


function confirmPurchase()
    GºinStateº(State.Created)          // precondition
    Gºrequireº(msg.value == 2 * value) // precondition
    B*// VISIBILITY MODIFIERS (Required 0.5+) {*
    Bº[internal] ← only this contract and child onesº
    Bº[private]  ← only this contractº
    Bº[external] ← will only ever be called externallyº
    Bº             external is more efficient than publicº
    Bº             since it also avoid copying parameters twiceº
    Bº             (very important with big arrays!!!)º
    Bº[public]   ← will also be called internally.º
    B*// }*
    O*// MUTABILITY MODIFIERS {*
    Oº[payable]  /* allows funct to receive ether when called as:º
    Oº            º myContractInstance.myPayableFunction.call. \*
    Oº            º   value("ETH_TO_BE_SENT")("ADDITIONAL_DATA")*
    Oº            º Ej:*
    Oº            º   function deposit() payable {*
    Oº            º     deposits[msg.sender] += msg.value;*
    Oº            º   };*
    Oº            º/*
    Oº[pure]      /* does NOT modify the contract storageº
    Oº             º and storage can NOT be accesed*
    Oº             º (utility libraries, ...)*/*
    Oº[view] /* does NOT modify the contract storageº
    Oº          but storage can be accesed  ("getters")º/*
    Oº[constant] /* alias for pure º/*
    O*// }*
    Qº[returns ('return types')]º
    {
      // (function body)
      ...
    }

Note:
     confirmPurchase(...) # Internal call
this.confirmPurchase(...) # External call
IMPORTS:
import "filename";
import * as symbolName from "filename";
import {symbol1 as alias, symbol2} from ""filename"";
import ""filename"" as symbolName;

Frameworks like truffle will also automatically import from the "node_modules/" folder
where npm (Node package manager) installs dependencies.

Fallback fn.
(called when no other function matches)
event EventFallback(address from, int256 amount);
...
function () payable {
  if (! this.owner.send(amount)) { throw ; }
  EventFallback(msg.sender, receiver, amount);
};

event EventFallback(address from, int256 amount);
...
function () payable {
  if (! this.owner.send(amount)) { throw ; }
  EventFallback(msg.sender, receiver, amount);
};
UUID: 080d788a-24ab-4469-aec2-05c111c60db9

ERROR CONTROL
@[https://solidity.readthedocs.io/en/v0.4.24/control-structures.html#error-handling-assert-require-revert-and-exceptions]
Solidity uses state-reverting exceptions to handle errors:
 - Capturing ("catch-ing") Exceptions IS NOT (YET?) POSSIBLE (2018-06-11)!.
 - EVM rollbacks any stat change in current call and all its sub-calls
   including events pending to register.
   (there is no safe way to continue execution while warrantying atomicity
    and reproducibility of results)
 - TX is still mined and TXReceipt status flaged with "fail" error
   See Example failed TX mined

PROGRAMATICALLY TRIGGERING EXCEPTIONS:
┌───────────────────────────────────────────────┬──────────────────────────────────────────────┬───────────────────────────────────────────────┐
│      assert                                   │     require                                  │   revert                                      │
├───────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ (programming error)                           │ (pre/post check in in/out-data)              │ (business logic exceptions)                   │
├───────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ - Check for conditions and throw an exception │ - Check for conditions and throw an exception│ - replaces deprecated 'throw'                 │
│   if the condition is not met                 │   if the condition is not met                │ - can be used to flag an error and revert the │
│ - Should only be used to test for internal    │ - Should be used to ensure valid conditions, │   current call.                               │
│   errors, and to check invariants             │   such as inputs, or contract state variables│ - It is possible to provide a string message  │
│ - If used properly, analysis tools can        │   are met, or to validate return values from │   containing details about the error that will│
│   evaluate your contract to identify          │   calls to external contracts                │   be passed back to the caller.               │
│   the conditions and function calls which will│ - optionally a message-string can be provided│                                               │
│   reach a failing assert.                     │                                              │                                               │
│   Properly functioning code should never reach│                                              │                                               │
│   a failing assert statement                  │                                              │                                               │
├───────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ - compiles to INVALID 0xfe instruction        │  - compiles to REVER 0xfd instruction        │                                               │
├───────────────────────────────────────────────┼──────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ assert( "my code-logic assertion")            │ require("required cond.", "messsage");       │  if ("not condtion for input") revert("....") │
└───────────────────────────────────────────────┴──────────────────────────────────────────────┴───────────────────────────────────────────────┘

┌─────────┬────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────┐   ┌─────────────────────────────────────────────────────┐
│         │ assert-style exception                                 │ revert/require-style exception                       │   │low level ops (return false, no exception raised)    │
├─────────┼────────────────────────────────────────────────────────│──────────────────────────────────────────────────────│   │─────────────────────────────────────────────────────│
│Condition│ - access array at index greater than array             │ - Calling throw (deprecated)                         │   │- create a contract using "new" but contract creation│
│that     │  length (or negative)                                  │ - Calling require evaluating to false                │   │  does not finish properly.                          │
│triggers │ - access fixed-length bytes"N" at a too large or       │ - call a function via a message call but it does not │   │- perform external function call targeting a contract│
│exception│   negative index                                       │   finish properly (i.e. it runs out of gas, has no   │   │  that contains no code                              │
│in the   │ - divide or modulo by zero (ex.: 5 / 0 , 23 % 0)       │   matching function, or throws an exception itself), │   │- contract receives Ether via public function        │
│at (EVM) │ - shift by a negative amount                           │   except when a low level operation call, send,      │   │  without payable modifier (including constructor    │
│runtime  │ - convert a value too big|negative into an enum type   │   delegatecall or callcode is used.                  │   │  or fallback                                        │
│         │ - call to zero-initialized variable of internal        │                                                      │   │- contract receives Ether via public getter function │
│         │   function type                                        │                                                      │   │- .transfer() fails                                  │
│         │ - call assert with an argument that evaluates to false │                                                      │   │                                                     │
│         │ - call function not matching any func. in contract     │                                                      │   │                                                     │
├─────────┼────────────────────────────────────────────────────────│──────────────────────────────────────────────────────│   │─────────────────────────────────────────────────────│
│Gas ussag│ Consume all gas available to the call                  │ - Do NOT consume any gas (v.Metrópolis+)             │   │                                                     │
├─────────┼────────────────────────────────────────────────────────│──────────────────────────────────────────────────────│   │─────────────────────────────────────────────────────│
│Propagati│ - Rethrown ("bubble up") in sub-calls                  │ - Rethrown ("bubble up") in sub-calls                │   │- return false *1                                    │
└─────────┴────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────┘   └─────────────────────────────────────────────────────┘
                                                                                                                                 *1 or true if called account is non-existent
                                                                                                                                    Existence must be checked prior to call

Solidity compiler automatically generate exceptions (assert or require/revert?) if:
 - If your contract receives Ether via a public function without payable modifier
   (including the constructor and the fallback function)
 - If your contract receives Ether via a public getter function
 - If you call a zero-initialized variable of internal function type
 - If a addressInstance.transfer() fails


The provided string in require/revert will be abi-encoded as if it were a call to a function Error(string).
For example:
   revert("Not enough Ether provided."); will cause the following hexadecimal data be set as error return data:

0x08c379a0                                                         // Function selector for Error(string)
0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset
0x000000000000000000000000000000000000000000000000000000000000001a // String length
0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data


revert reason@clients
Since Solidity 0.4.22 the require() and revert() operation optionally 
take a revert reason as argument: Revert with reason.
This is accessible for eth_calls in the result field.

Clients libraries will eventually support fetching such value. 
Ex: web3j REF: @[https://github.com/web3j/web3j/issues/858]

Have a method public String getRevertReason() on 
org.web3j.protocol.core.methods.response.EthCall that retrieves 
that revert reason.

See also (future/rejected?) proposal Typed Errors EIP 838
@[https://github.com/ethereum/EIPs/issues/838].
Ex of proposal:
contract MyToken {
 ºerror InsufficientFunds(uint256 amount, uint256 balance);º // ← Strongly typed error

  function ... {
    if (! "assertCondition")
       throw InsufficientFunds(_amount, balances[msg.sender]);
    ...
  }
  ...
}
storage
 patterns
@[https://ethereum.stackexchange.com/questions/13167/are-there-well-solved-and-simple-storage-patterns-for-solidity]
Q: Simple and appropriate data organization can challenge Solidity newcomers.
  It wants us to organize everything in ways many of us aren’t accustomed to.
  Are there well-solved general patterns for routine on-chain data organization?

A: Here are some simple and useful patterns in increasing order of utility.
ºEvent logs are omitted for brevity. In practice, it's desirable to emit events for every important state change.º

ºSIMPLE LIST USING ARRAYº
  STRENGTHS                    | WEAKNESSES                      | EXAMPLE:
  Reliably chronological order | No random access by Id          | pragma solidity ^0.4.6;
  Provides a count             | No assurance of uniqueness      | contract simpleList {
  Random access by Row Number  | No check for duplicates         |   struct EntityStruct {
  (not Id)                     | Uncontrolled growth of the list |     address entityAddress;
                               |                                 |        uint entityData;
                               |                                 |      }
                               |                                 |
                               |                                 |      ºEntityStruct[]º public entityStructs;
                               |                                 |
                               |                                 |      function newEntity(address entityAddress, uint entityData)
                               |                                 |          public returns(uint rowNumber) {
                               |                                 |        EntityStruct memory newEntity;
                               |                                 |        newEntity.entityAddress = entityAddress;
                               |                                 |        newEntity.entityData    = entityData;
                               |                                 |        return entityStructs.push(newEntity)-1;
                               |                                 |      }
                               |                                 |
                               |                                 |      function getEntityCount()
                               |                                 |          public constant returns(uint entityCount) {
                               |                                 |        return entityStructs.length;
                               |                                 |      }
                               |                                 |    }

ºMAPPING WITH STRUCTº
  STRENGTHS                    | WEAKNESSES                      | EXAMPLE:
 -Random access by unique Id   |-Unable to enumerate the keys    | contract mappingWithStruct {
 -Assurance of Id Uniqueness   |-Unable to count the keys        |   struct EntityStruct {
 -Enclose arrays, mappings,    |-Needs a manual check to         |     uint entityData;
  structs within each "record" |-distinguish a default from      |     bool isEntity;
                               | an explicitly "all 0" record    |   }
                               |                                 |
                               |                                 |   ºmapping (address =˃ EntityStruct)º
                               |                                 |     public entityStructs;
                               |                                 |   function isEntity(address entityAddress)
                               |                                 |      public constant returns(bool isIndeed) {
                               |                                 |      return entityStructs[entityAddress].isEntity;
                               |                                 |   }
                               |                                 |
                               |                                 |   function newEntity
                               |                                 |       (address entityAddress, uint entityData)
                               |                                 |       public returns(bool success) {
                               |                                 |     if(isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress].entityData
                               |                                 |        = entityData;
                               |                                 |     entityStructs[entityAddress].isEntity
                               |                                 |        = true;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 |
                               |                                 |   function deleteEntity(address entityAddress)
                               |                                 |     public returns(bool success) {
                               |                                 |     if(!isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress].isEntity = false;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 |
                               |                                 |   function updateEntity
                               |                                 |       (address entityAddress, uint entityData)
                               |                                 |       public returns(bool success) {
                               |                                 |     if(!isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress].entityData
                               |                                 |       = entityData;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 | }


ºARRAY OF STRUCTS WITH UNIQUE IDSº

  STRENGTHS                    | WEAKNESSES                      | EXAMPLE:
- Random access by Row number  | - No random access by Id        | contract arrayWithUniqueIds {
- Assurance of Id uniqueness   | - Uncontrolled growth of        |
- Enclose arrays, mappings     |   the list                      |   struct EntityStruct {
  and structs with each        |                                 |     address entityAddress;
  "record"                     |                                 |     uint entityData;
                               |                                 |   }
                               |                                 |
                               |                                 |   EntityStruct[] public entityStructs;
                               |                                 |   mapping(address =˃ bool) knownEntity;
                               |                                 |
                               |                                 |   function isEntity(address entityAddress)
                               |                                 |       public constant returns(bool isIndeed) {
                               |                                 |     return knownEntity[entityAddress];
                               |                                 |   }
                               |                                 |
                               |                                 |   function getEntityCount() public constant
                               |                                 |        returns(uint entityCount) {
                               |                                 |     return entityStructs.length;
                               |                                 |   }
                               |                                 |
                               |                                 |   function newEntity(
                               |                                 |       address entityAddress, uint entityData)
                               |                                 |       public returns(uint rowNumber) {
                               |                                 |     if(isEntity(entityAddress)) throw;
                               |                                 |     EntityStruct memory newEntity;
                               |                                 |     newEntity.entityAddress = entityAddress;
                               |                                 |     newEntity.entityData = entityData;
                               |                                 |     knownEntity[entityAddress] = true;
                               |                                 |     return entityStructs.push(newEntity) - 1;
                               |                                 |   }
                               |                                 |
                               |                                 |   function updateEntity(
                               |                                 |       uint rowNumber,
                               |                                 |       address entityAddress,
                               |                                 |       uint entityData) public returns(bool success) {
                               |                                 |     if(!isEntity(entityAddress)) throw;
                               |                                 |     if(entityStructs[rowNumber].entityAddress
                               |                                 |       != entityAddress) throw;
                               |                                 |     entityStructs[rowNumber].entityData
                               |                                 |       = entityData;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 | }

ºMAPPED STRUCTS WITH INDEXº
  STRENGTHS                    | WEAKNESSES                      | EXAMPLE:
- Random access by unique Id   | - Uncontrolled growth of        | contract MappedStructsWithIndex {
  or row number                |   the list                      |
- Assurance of Id uniqueness   |                                 |   struct EntityStruct {
- Enclose arrays, mappings and |                                 |     uint entityData;
  structs within each "record" |                                 |     bool isEntity;
- List maintains order of      |                                 |   }
  declaration                  |                                 |
- Count the records            |                                 |   mapping(address =˃ EntityStruct)
- Enumerate the Ids            |                                 |       public entityStructs;
- "Soft" delete an item by     |                                 |   address[] public entityList;
  setting a boolean            |                                 |
                               |                                 |   function isEntity(address entityAddress)
                               |                                 |       public constant
                               |                                 |       returns(bool isIndeed) {
                               |                                 |     return entityStructs[entityAddress].isEntity;
                               |                                 |   }
                               |                                 |
                               |                                 |   function getEntityCount()
                               |                                 |       public constant
                               |                                 |       returns(uint entityCount) {
                               |                                 |     return entityList.length;
                               |                                 |   }
                               |                                 |
                               |                                 |   function newEntity(
                               |                                 |       address entityAddress,
                               |                                 |       uint entityData)
                               |                                 |        public returns(uint rowNumber) {
                               |                                 |     if(isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress].entityData
                               |                                 |        = entityData;
                               |                                 |     entityStructs[entityAddress].isEntity
                               |                                 |        = true;
                               |                                 |     return
                               |                                 |       entityList.push(entityAddress) - 1;
                               |                                 |   }
                               |                                 |
                               |                                 |   function updateEntity
                               |                                 |       (address entityAddress, uint entityData)
                               |                                 |       public returns(bool success) {
                               |                                 |     if(!isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress].entityData
                               |                                 |       = entityData;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 | }


ºMAPPED STRUCTS WITH DELETE-ENABLED INDEXº
REF@Medium Rob Hitchens
BitBucket Source Code
  STRENGTHS                    | WEAKNESSES                      | EXAMPLE:
- Random access by unique Id   | - Marginally increased code     | contract mappedWithUnorderedIndexAndDelete {
  or row number                |   complexity                    |   struct EntityStruct {
- Assurance of Id uniqueness   | - Marginally higher storage     |     uint entityData;
- Enclose arrays, mapping and  |   costs                         |     uint listPointer;
  structs within each "record" | - Key list is inherently        |   }
- Count the records            |   unordered                     |
- Enumerate the ids            |                                 |   mapping(address =˃ EntityStruct) public entityStructs;
- Logically control the size of|                                 |   address[] public entityList;
  the active list with delete  |                                 |
  function                     |                                 |   function isEntity(address entityAddress)
                               |                                 |       public constant returns(bool isIndeed) {
                               |                                 |     if(entityList.length == 0) return false;
                               |                                 |     return (
                               |                                 |       entityList[entityStructs[entityAddress].
                               |                                 |          listPointer] == entityAddress);
                               |                                 |   }
                               |                                 |
                               |                                 |   function getEntityCount()
                               |                                 |       public constant
                               |                                 |       returns(uint entityCount) {
                               |                                 |     return entityList.length;
                               |                                 |   }
                               |                                 |
                               |                                 |   function newEntity(
                               |                                 |       address entityAddress,
                               |                                 |       uint entityData)
                               |                                 |       public returns(bool success) {
                               |                                 |     if(isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress].entityData
                               |                                 |         = entityData;
                               |                                 |     entityStructs[entityAddress].listPointer
                               |                                 |         = entityList.push(entityAddress) - 1;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 |
                               |                                 |   function updateEntity(
                               |                                 |       address entityAddress,
                               |                                 |       uint entityData)
                               |                                 |       public returns(bool success) {
                               |                                 |     if(!isEntity(entityAddress)) throw;
                               |                                 |     entityStructs[entityAddress]
                               |                                 |        .entityData = entityData;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 |
                               |                                 |   function deleteEntity(address entityAddress)
                               |                                 |       public returns(bool success) {
                               |                                 |     if(!isEntity(entityAddress)) throw;
                               |                                 |     uint rowToDelete
                               |                                 |       = entityStructs[entityAddress].listPointer;
                               |                                 |     address keyToMove
                               |                                 |       = entityList[entityList.length-1];
                               |                                 |     entityList[rowToDelete] = keyToMove;
                               |                                 |     entityStructs[keyToMove].listPointer
                               |                                 |       = rowToDelete;
                               |                                 |     entityList.length--;
                               |                                 |     return true;
                               |                                 |   }
                               |                                 |
                               |                                 | }


if(bad) throw;
if(bad) revert();
require(!bad)
ethfiddle.com/PgDM-drAc9
STRUCTS
@[https://solidity.readthedocs.io/en/latest/structure-of-a-contract.html#struct-types]


- Starting with Solidity 0.5+ explicit data location (memory, storage, calldata)
  for all variables of struct, array or mapping types is mandatory. This is also
  applied to function parameters and return variables.  

Returning
Structs
- REF:
@[https://medium.com/coinmonks/solidity-tutorial-returning-structs-from-public-functions-e78e48efb378]
- Solidity (0.4.13, as of this writing), doesn't allow
  to return a struct from public functions.
  (allowed by experimental ABIv2)

ºRETURNING ARRAYS OF STRUCTS:                                     │ ºJS Client code:*
                                                                  │  """Getting data back in this format is, admittedly, a pain to
 pragma solidity ^0.4.13;                                         │  deal with on the frontend:"""
                                                                  │
 contract Project {                                               │ const people = await project.ºgetPeopleº([ 2, 5 ])
     struct Person {                                              │       ^^^^^^
       Gºaddress addrº;                                           │     [
       Bºuint fundsº;                                             │      ['0xdeadbeef', '0xabcdeff'], // ← Gºaddrsº
     }                                                            │      [        100 ,        789 ]  // ← Bºfundsº
                                                                  │     ]
     Person[] people;                                             │
                                                                  │       ^^^^^^^^^^^ ,  ^^^^^^^^^^^
     functionºgetPeopleº(uint[] indexes) public                   │       - struct1 - ,  - struct2 -
         returns (Gºaddress[]º, Bºuint[]º) {                      │
         //       ^^^^^^^^^^^^^^^^^                               │ constGºFIELD_ADDR º= 0
         //       One array for each struct field                 │ constBºFIELD_FUNDSº= 1
       Gºaddress[] memory addrs = new address[](indexes.length);º │
       Bºuint[]    memory funds = new uint[](indexes.length);º    │ let peopleStructs = []
                                                                  │ for (let i = 0; i ˂ numPeople; i++) {
         for (uint i = 0; i ˂ indexes.length; i++) {              │     const person = {
             Person storage person = people[indexes[i]];          │         addr:  people[FIELD_ADDR][i],
             addrs[i] = person.addr;                              │         funds: people[FIELD_FUNDS][i],
             funds[i] = person.funds;                             │     }
         }                                                        │     peopleStructs.push(person)
         return (addrs, funds);                                   │ }
     }                                                            │
 }                                                                │
enums
@[https://solidity.readthedocs.io/en/latest/structure-of-a-contract.html#enum-types]
enum State { Created, Locked, Inactive } // ← Definition
State  s1 = State.Created                // ← Ussage
uint8  u1 = uint8 (State.Created)        // ← Explicit uintXX to enum
uint16 u2 = uint16(State.Created)
State  s2 = State(u1)                    // ← uintXX to enum using enum constructor
                                              Will raise an assert exception if
                                              u1 is outside the State bounds.
Linked List
@[https://github.com/vittominacori/solidity-linked-list]
Arrays
@[https://solidity.readthedocs.io/en/v0.4.24/types.html#arrays
Syntax:

uint[100] memory fixedArray;     ← Fixed   Size Array declaration
          fixedArray[0] = 1;
          fixedArray[1] = 2;
          fixedArray.push(3);    ← RºError. Not allowed for fixed size arrayº
          ...
uint[ ] memory  dynArray1 = unit[] ← Dynamic Size Array declaration
          dynArray1.push(1)        ← RºError. Not allowed for memory arrayº
          ...
uint[ ] storage dynArray2 = unit[] ← Dynamic Size Array declaration
          dynArray2.push(1 )       ← GºOKº
          ...
var x          = uint[][5]      ← Fixed-(5)size-array of
                                  dynamic-uint-arrays  (var for type inference)
    x[2][1]                     ← second uint in third dyn-array


 ┌────────┬───────────────────────┬───────────────────┬──────────────────────┬────────────────────┐
 │        │ Admited type          │ Creation          │ Resize               │ Delete             │
 ├────────┼───────────────────────┼───────────────────┼──────────────────────┼────────────────────┤
 │Storage │ ºanyº                 │ (just declare it) │- set/reassign .length│ delete myArray;    │
 │Arrays  │                       │                   │- push(el)            │ myArray.length = 0;│
 ├────────┼───────────────────────┼───────────────────┼──────────────────────┼────────────────────┤
 │Memory  │ ºanyº but mapping     │ Use 'new'         │ Not allowed          │                    │
 │Arrays  │ (ABI comp. for        │ new uint[](7)     │(fix size determined  │                    │
 │        │  public/extern fun)   │ new bytes(len)    │ at runtime)          │                    │
 └────────┴───────────────────────┴───────────────────┴──────────────────────┴────────────────────┘
ºSpecial arrays(tightly packed in calldata)º
bytes : byte[]

string: (UTF-8) similar to bytes
        -  does not YET allow length/index/push access
        Use use bytes(myString).length / bytes(myString)[7] = 'x' to
        access the low-byte-representation of myString

- Array Literals expression (not immediately assigned to a variable)
  - type     : memory array of fixed length.
  - base type: common type of array elements.
  ...
  calledFunction(Oº[uint(1), 2, 3]º);

ºLimitations:º
  - arrays of arrays not (YET) allowed in external functions
  - (EVM limitation): dynamic content NOT allowed in external-function return-value
    - Workaround: use large statically-sized arrays
  - Deleting an element in the array (delete myArray[idx1]) generates gaps over time
  - This can lead to unpredictable gas costs if a contract itself has to search
    through those gaps.

Walk over
WARN: ºstring[]  arrays not allowed in solidityº
bytes32[] storage public namesInUse;
uint arrayLength = namesInUse.push(1); // Returns 1
     arrayLength = namesInUse.push(3); //   "     2
           ^^^^
           push only allowed for storage arrays, not memory
assert(arrayLength == namesInUse.length);
for (uint i = 0; i ˂ namesInUse.length; i++) {
   require(namesInUse[i] != username);
}
Mappings
@[https://solidity.readthedocs.io/en/v0.4.24/types.html#mappings]
Syntax:

   mapping(_KeyType =˃ _ValueType) public myMapping; // ← Declatarion
           ^^^^^^^^
     almost any type except
     mapping,dynamic array,
     contract,enum,struct

   myMapping[key1] = value1;                         // ← add/modify key
   delete myMapping[key1]                            // ← put myMapping[key] to virt.Zero


- Only allowed for state variables (or as storage reference types in internal functions)
- ºare NOT iterable.º

  - Care must be taken to not leave orphaned data in the state database,
    particularly after contract-self-destruction =˃
    - code must manually clean mappings by deleting each key.

Walk over
- Mappings are virtually initialized:
  - ºevery possible key exists mapped to zero-byte-reprº
  - keys are NOT stored in the map
    =˃ Code needs the keys to discover/walk-over mappings.
  - values are stored at the state-memory address == sha3(key)

- Solution 1: Using aux. array to store keys.
  (memory gaps can arise when deleting the aux-key-array)
 ┌───────────────────────────────────────────┬──────────────────────────────────────────┐
 │ETHEREUM CODE                              │ CLIENT CODE                              │
 ├───────────────────────────────────────────┼──────────────────────────────────────────┤
 │mapping (address =˃ uint) public balances; │ for(i = 0; i ˂ k.size(); i++) {          │
 │address[] public keyList   ;               │   someFunc( k.balances(k.keyList(i)) );  │
 │function size() public returns (uint) {    │ }                                        │
 │    return keyList.length;                 │ Note: k == contract instance             │
 │}                                          └──────────────────────────────────────────┤
 │WARN: delete keyList[idx] can leave gaps                                              │
 └──────────────────────────────────────────────────────────────────────────────────────┘
- Solution 2: Using Linked List Indexes
 ┌───────────────────────────────────────────┬──────────────────────────────────────────┐
 │ETHEREUM CODE                              │ CLIENT CODE                              │
 ├───────────────────────────────────────────┼──────────────────────────────────────────┤
 │mapping (address =˃ address) ll;           │ var current = k.ll(0);                   │
 │mapping (address =˃ uint) public balances; │ while (current) {                        │
 │function add(address _addr_as_idx) public  │     console.log( k.balances(current) );  │
 │{                                          │     current = k.ll(current);             │
 │    ll[_addr]  = ll[0x0];                  │ }                                        │
 │    ll[0x0]    = _addr;                    └──────────────────────────────────────────┤
 │    balances[_addr] = balance;                                                        │
 │}   ^^                                                                                │
 │ ll will grow as:                                                                     │
 │   STEP 1         → STEP 2         → STEP 3         → STEP 4 ...                      │
 │   0x      addr01 → 0x      addr02 → 0x      addr03 →                                 │
 │                  → addr02  addr01 → addr02  addr01 →                                 │
 │                  →                → addr03  addr02 →                                 │
 │                  →                → addr03  addr02 →                                 │
 │                                                                                      │
 │// Deleting: No gaps but require a search to find parent node                         │
 │function remove(address _addr) {                                                      │
 │      address parent;                                                                 │
 │      // Warning: unbounded gas loop                                                  │
 │      while (llIndex[parent] != _addr) parent = llIndex[parent];                      │
 │      llIndex[parent] = llIndex[ llIndex[parent]];                                    │
 │      delete llIndex[address];                                                        │
 │      delete balances[address];                                                       │
 │  }                                                                                   │
 └──────────────────────────────────────────────────────────────────────────────────────┘
- Solution 3: Using Double Linked List Indexes
   - search loops removes at the expense of extra storage slot per indexed element.
   - a nested bool mapping for bidirectional links where we interpret
      PREV == false and NEXT == true:
┌──────────────────────────────────────────────────────────────────────────────────────┐
│mapping(address =˃ ( mapping(bool =˃ address) ) dllIndex;                             │
│mapping(address =˃ uint) balances;                                                    │
│function add(address _addr)                                                           │
│{                                                                                     │
│    // Link the new node                                                              │
│    dllIndex[_addr][PREV] = 0x0;                                                      │
│    dllIndex[_addr][NEXT] = dllIndex[0x0][NEXT];                                      │
│                                                                                      │
│    // Insert the new node                                                            │
│    dllIndex[dllIndex[0x0][NEXT]][PREV] = _addr;                                      │
│    dllIndex[0x0][NEXT] = _addr;                                                      │
│}                                                                                     │
│                                                                                      │
│function remove(address _addr)                                                        │
│{                                                                                     │
│    // Stitch the neighbours together                                                 │
│    dllIndex[ dllIndex[_addr][PREV] ][NEXT] = dllIndex[_addr][TRUE];                  │
│    dllIndex[ dllIndex[_addr][NEXT] ][PREV] = dllIndex[_addr][PREV];                  │
│                                                                                      │
│    // Delete state storage                                                           │
│    delete dllIndex[_addr][PREV];                                                     │
│    delete dllIndex[_addr][NEXT];                                                     │
│    delete balances[_addr];                                                           │
│}                                                                                     │
└──────────────────────────────────────────────────────────────────────────────────────┘
 - We now have a directly addressable and fully iterable storage structure, which is
   not just a Double Linked List but a Circular Double Linked List by default
   with the head at 0x0. This gives us two very desirable properties for free...

 - FIFO and FILO Queues
    First In First Out (FIFO) and First In Last Out (FILO) queues are a very
    common concept in computing. FIFO can be used for task queues while FILO
    is also used for memory 'stacks'.

 - FIFO's can be used in any contracts that require atomic sequential order
   processing. Here a new order is simply inserted previous to the head,
   while the oldest order is simply taken from next to the head. No search
   loops required.

 - If you think these structures might be useful, check out my Circular
   Double Linked List Index Library which is used by my Intrinsically
   Tradable Tokens (ITT) contract.

Iterable map
(arachnid gist)
@[https://gist.github.com/ethers/7e6d443818cbc9ad2c38efa7c0f363d1]
library itmap {
    struct entry {
        // Equal to the index of the key of this item in keys, plus 1.
        uint keyIndex;
        uint value;
    }

    struct itmap {
        mapping(uint =˃ entry) data;
        uint[] keys;
    }

    function insert(itmap storage self, uint key, uint value) internal returns (bool replaced) {
        entry storage e = self.data[key];
        e.value = value;
        if (e.keyIndex ˃ 0) {
            return true;
        } else {
            e.keyIndex = ++self.keys.length;
            self.keys[e.keyIndex - 1] = key;
            return false;
        }
    }

    function remove(itmap storage self, uint key) internal returns (bool success) {
        entry storage e = self.data[key];
        if (e.keyIndex == 0)
            return false;

        if (e.keyIndex ˂ self.keys.length) {
                      // Move an existing element into the vacated key slot.
                      self.data[self.keys[self.keys.length - 1]].keyIndex = e.keyIndex;
                      self.keys[e.keyIndex - 1] = self.keys[self.keys.length - 1];
                      self.keys.length -= 1;
                      delete self.data[key];
                      return true;
                  }
              }

              function contains(itmap storage self, uint key) internal constant returns (bool exists) {
                  return self.data[key].keyIndex ˃ 0;
    }

    function size(itmap storage self) internal constant returns (uint) {
        return self.keys.length;
    }

    function get(itmap storage self, uint key) internal constant returns (uint) {
        return self.data[key].value;
    }

    function getKey(itmap storage self, uint idx) internal constant returns (uint) {
        return self.keys[idx];
    }
}

contract Test {
    // Use itmap for all functions on the struct
    using itmap for itmap.itmap;

    // Declare an iterable mapping
    itmap.itmap mymap;

    function insert(uint key, uint value) {
        mymap.insert(key, value);
    }

    function get(uint key) returns (uint value) {
        return mymap.get(key);
    }
}
Quality Assurance
Static/Dynamic
code analysis
by QuillAudits, security Firm
@[https://blog.quillhash.com/static-and-dynamic-analysis-of-smart-contracts-vulnerabilities/]
@[https://audits.quillhash.com]

ºSTATIC ANALYSISº
- Smart Contract Analysis types:

 STEP 1      STEP 2       STEP 3        STEP 4        STEP 5 @1
────────    ──────────   ───────────   ─────────   ───────────────────────
Solidity    compiler     Recover       functions   known attacks detection
Source   →  sol       →  meaninful   → modifiers →
Code        --ast-json   information   variables   Gas optimizer linters
                         from          ...
                         ast-tree
────────    ──────────   ───────────   ─────────   ───────────────────────

@1: STEP 5: STATIC CODE ANALYSIS
(Find bugs that the standar compiler is not able to detect)

  KNOW ATTACKS TESTS                SEVERITY LEVEL
  -----------------------------     --------------
  - Reentrancy                      - High
  - uninitialized states            - Medium
  - unused internal functions       - Low
  - Functions Transferring ethers   - Informational
    (check modifiers/authenticity)
  - Ether lock
  - Gas optimization etc.


STATIC CODE ANALYSIS LIMITATIONS:
- It is not a complete security tool.
- Only known attacks or predefined rules
  can be scanned.

ºDYNAMIC ANALYSISº
- Dyn.Ana. tests the code in a run-time setup
- Dummy (or boundary) values are taken as input
  according to the conditions of function.

- Most of the dynamic analysis tools use:
  - symbolic analysis
  - fuzzers
  - formal verification to secure smart contract.

-ºsymbolic analysisº
 means of analyzing a program to determine what inputs
 cause each part of a program function to execute.

ºCompared to traditional functional testingº
- function "input values" are used to test function i.e ‘123’, ‘Hello’ concrete values,
- Symbolic analysis: no specific input is taken at present but a default value:
  - let's say ƛ is taken as an input after reaching at conditional statement it fork
    the state and two different values are taken.

Ex: Our goal will be to see if we can use symbolic analysis
    to show that it is possible to get the result of the next function
    to be 100.

 01 function test(uint256 value) public pure returns(int) {
 02   uint result = 0;
 03   if (value ˃ 100) {
 04     result += 100;
 05   }
 06   return result;
 07 }

  NORMAL DYNAMIC TESTING  | SYMBOLIC ANALYSIS
  (input = 50)            | (input = ƛ)
--------------------------+-------------------------
  value  = 50 (line 1)    |        value  =  ƛ (line 1)
                          |
  value  = 50 (line 2)    |        value  =  ƛ (line 2)
  result =  0             |        result =  0
                          |
  value  = 50 (line 3)    |        value  =  ƛ (line 3)
  result =  0             |        result =  0
                          |
  value  = 50 (line 7)    | value  =  ƛ (line 7)       value  = ƛ    (line 4)
 ºresult =  0º            |ºresult =  0 if ƛ˂=100º     result = 100  if ƛ˃100
                          |
                          |                            value  = ƛ    (line 7)
                          |                           ºresult = 100º if ƛ˃100



ºwe use symbolic analysis to find the input values to execute functionº
 input_list [ ˂=100, ˃100 ]

-ºFUZZING SMART CONTRACTº
- Type of testing in which seed inputs or set of inputs are taken
  to discover new inputs automatically  that might highlight coding
  errors or security loopholes in smart contracts, by inputting
  invalid or random data called FUZZ to the smart contract.
  After which the smart contracts are monitored for various path
  generated or error handling.


Analyze     extract Data type   ABI signature   generate Fuzzing
Byte Code → and signature of  → analysis      → inputs, based on  →
+ ABI       of functions                        first 3 steps

   Fuzzing      Vulnerability
 → proccess  →  analysis, based on
   starts       generated logs

- fuzzer can be classified into three categories based
  on testing techniques:
   -  Black box testing
     ºThe fuzzer didn't get any information about the contractº
      performing millions of mutants( inputs ) while testing
      a smart contract.
      - PROS:
        - Millions of input values in few seconds is used to
          find loopholes in smart contracts.
      - CONS:
        - statement or code coverage is "random"

   -  White box testing
     ºfuzzer have information about smart contracts input valuesº
      They use symbolic analysis to test smart contracts,
      - PROS:
        - cover most of the paths
        - It wil use multiple searching techniques to
          generate new paths like heuristic searching technique.
   -  Grey box testing
     ºfuzzer has partial knowledge of smart contractsº
      They are the most popular fuzzers in finding the
      vulnerability of smart contracts.
      - lightweight testing approach that effectively
        detects bugs and security vulnerabilities.
      - greybox fuzzers randomly mutate program inputs
        to exercise new paths; this makes it challenging
        to cover code that is guarded by complex checks
      - PROS:
        - cover most of the paths
Grey box Fuzzing and formal verification are a very popular way to
secure smart contracts these days but didn’t get the edge yet,
tools under these techniques are still under development or not
production-ready.

TODO: In upcoming articles, we will discuss what is formal verification
      and how formal verification can help in securing smart contracts.

REFS:
@[https://arxiv.org/pdf/1807.03932.pdf]
@[https://arxiv.org/pdf/1807.07875.pdf]

QuillAudits is a secure smart contract audits platform designed by QuillHash
Technologies. It is a fully automated platform to verify smart contracts to
check for security vulnerabilities through its superior manual review and 
automated tools. We conduct both smart contract audits and penetration tests
to find potential security vulnerabilities which might harm the platform’s integrity.

To be up to date with our work, Join Our Community:

Telegram | Twitter | Facebook | LinkedIn
Audit
Blockchain Technology
Ethereum
quillhash
Smart Contracts

Post navigation
Checkout Our Smart contract Audit Process and OxyCoin Audit Report.
Previous Post

Btccredit Smart Contract Final Audit Report
D dR7j5UEAAP9nI
Next Post

dNFTs : Distributed Ownership of NFTs on EOS
Search for:
Stay Connected

In Trend

    ASMX
    Asmx Smart Contracts Audit Report
        Posted byQuillhash Team
        April 10, 2019
    Ethereum or Hyperledger Fabric
    Ethereum or Hyperledger Fabric?
        Posted byQuillhash Team
        March 19, 2019
    3rd party security audit
    Digipharm Smart Contract Audit Report
        Posted byQuillhash Team
        June 11, 2019
    Tokenic partners with kyber Network — allowing Projects to expand available payment methods for investors in Token Sale
    Tokenic partners with kyber Network  – Allowing Projects to expand available payment methods for investors in Token Sale
        Posted byQuillhash Team
        March 26, 2019
    D dR7j5UEAAP9nI
    dNFTs : Distributed Ownership of NFTs on EOS
        Posted byQuillhash Team
        August 1, 2019
    BlockWRK
    Blockwrk smart contract audit report
        Posted byQuillhash Team
        April 10, 2019
    Understanding The Basics Of Stellar Network
    Understanding The Basics Of Stellar Network
        Posted byQuillhash Team
        March 19, 2019
    Blockchain Weekly – Trends in Blockchain 5 featured 1
    Blockchain Weekly – Trends in Blockchain #5
        Posted byQuillhash Team
        June 11, 2019

Continue Reading

    D dR7j5UEAAP9nI
    dNFTs : Distributed Ownership of NFTs on EOS
        Posted byQuillhash Team
        August 1, 2019
    static dynamic 1
    Static and Dynamic analysis of smart contracts vulnerabilities
        Posted byQuillhash Team
        July 31, 2019
    Checkout Our Smart contract Audit Process and OxyCoin Audit Report.
    Btccredit Smart Contract Final Audit Report
        Posted byQuillhash Team
        July 19, 2019
    Checkout Our Smart contract Audit Process and OxyCoin Audit Report.
    FESSCHAIN SMART CONTRACT AUDIT REPORT
        Posted byQuillhash Team
        July 19, 2019
    EOS Crowdsale
    EOS Crowdsale – Develop Crowdsale smart contract on EOS
        Posted byQuillhash Team
        July 12, 2019
    IP Rights
    Protect intellectual property rights using blockchain.
        Posted byQuillhash Team
        July 8, 2019
    blockchain weekly 8
    Blockchain Weekly – Trends in Blockchain #8
        Posted byQuillhash Team
        July 3, 2019
    art industry
    Revolutionizing the art industry with blockchain
        Posted byQuillhash Team
        July 3, 2019

Related Posts
Let’s build something great. Together.

Just fill out the form and we’ll be in touch.


Name
Phone/Telegram/Email
MythX
@[https://docs.mythx.io/en/latest/index.html#]

MythX summary:
- Security analysis API that integrates with dev tools like Truffle,
  Visual Studio Code, Embark and Remix to allow security analysis right
  from the dev environment.


Extracted from:
@[https://media.consensys.net/mythx-pro-will-provide-the-most-robust-security-platform-in-the-ethereum-ecosystem-85c3465999b3]
"""Just two years ago, Mythril was launched to provide symbolic analysis for smart contracts.
  To date, the tool has been downloaded over 420,000 times. However, to keep up with the
  developing demands of smart contract developers and Dapp builders, there’s a strong need for
  an interconnected suite of security tools that covers a comprehensive detection surface area,
  and that can be utilized at all stages of the development lifecycle for an Ethereum-based 
  platform powered by smart contracts. Enter MythX.

   ....every time you do a pull request or every time you compile a contract, with MythX you can
   run a security analysis. MythX has a whole set of micro-services that 
  ºhandle symbolic analysis, dynamic analysis, static analysis, fuzzing, linting and other checks.º
  It can be run as a SaaS service. Users don’t have to run it on their own machines and use up
  computing cycles, and the service is always up-to-date.
  ºfree version runs between 30 seconds and two minutes.º That's what we call "quick" mode, and it
  is very useful for double checking small code changes on the fly

   MythX Pro 2019-09-09 will also to scan for many more of the SWC IDs (Smart Contract Weakness 
   Classification Registry) and for a longer amount of time, to get into deeper analysis.
  """
See also:
- Truffle Security extension:
@[https://github.com/ConsenSys/truffle-security"]
- 
- Minimum viable MythX client written in JavaScript.
  @[https://github.com/b-mueller/sabre]
- MythX Python library and CLI tool
  @[https://github.com/dmuhs/PythX]
QA: FORMAL PROBES
FORMAL Verification
https://github.com/pirapira/eth-isabelle
https://github.com/pirapira/ethereum-formal-verification-overview
Why3 Solidity
Why3 is a platform for deductive program verification. It provides a rich
language for specification and programming, called WhyML, and relies on
external theorem provers, both automated and interactive, to discharge
verification conditions. (See the specific section below for the list of
supported provers.) Why3 comes with a standard library of logical theories (
integer and real arithmetic, Boolean operations, sets and maps, etc.) and
basic programming data structures (arrays, queues, hash tables, etc.). A user
can write WhyML programs directly and get correct-by-construction OCaml
programs through an automated extraction mechanism. WhyML is also used as an
intermediate language for the verification of C, Java, or Ada programs. (See
Projects using Why3 below.) Why3 can be easily extended with support for new
theorem provers. Why3 can be used as a software library, through an OCaml API.

https://forum.ethereum.org/discussion/3779/formal-verification-for-solidity-contracts

"""
   We just merged a first pull request that allows Solidity contracts to be
   formally verified using a toolkit called why3.
   This means that a computer creates and checks a mathematical proof of
   assertions about the behaviour of the contract.
   Only a small subset of Solidity is supported for now, but that makes it
   already possible to verify a recursive binary search routine on arrays:
   https://gist.github.com/chriseth/0c671e0dac08c3630f47
"""

"""
   How to use it on the example
   The solidity compiler (only solc at latest develop for now) can translate the
   source code into a different programming language which can be understood by
   why3 (the language is a dialect of ocaml). To do that, call it as ""solc \-\-
   formal -o /tmp/output_directory/ source.sol"". Furthermore, using special
   tags in the Solidity comments of the form ""///@why3 ..."" you can formulate
   assertions and requirements that can be understood by the why3 framework and
   will be literally inserted into the generated code.


   start a graphical version of the toolkit and perform the verification.

   How to install why3
   I am not aware of any binary packages, so you have to download the source
   from the website.  As why3 itself is only a frontend to the real workhorses,
   the provers, you need to install a prover. I tried ""alt-ergo"" and Z3 - the
   first is part of the ubuntu distribution, the second has binaries for most
   platforms.

   After installing the prover (and making sure it is in the PATH), call ""why3
   config \-\-detect"" and it should detect your prover. """""""

   Video Tutorial:
   https://www.youtube.com/watch?v=Mzh4fyoaBJ0⅋feature=youtu.be⅋list=PL9oaY6Y4QxRZybj86eGItGVApxLXVIXHz
   https://gitter.im/ethereum/formal-methods
   "https://en.wikipedia.org/wiki/Logical_harmony

   Logical harmony, a name coined by Sir Michael Dummett, is a supposed
   constraint on the rules of inference (https://en.wikipedia.org/wiki/
   Rules_of_inference) that can be used in a given logical system(https://en.
   wikipedia.org/wiki/Logical_system)

See also:
Virt.Machine for interactive Theorem Provers
@[https://chriseth.github.io/notes/talks/formal_devcon2/#/]
@[http://www.cs.umd.edu/~aseem/solidetherplas.pdf]
Moonad
@[https://github.com/moonad/roadmap]
Moonad Roadmap
2018 Main Accomplishments:
  - Designed the first version of Formality with the aim of
    developing an efficient proof language for smart-contracts and
    applications. It included native datatypes and a prototypal
    interaction-net compiler.
  - Designed Symmetric Interaction Calculus, a parallel model of
    computation with applications to efficient, optimal and parallel
    evaluation of functional programs.
  - Explored it and wrote a blog post detailing our insights.

2019 Q1 Accomplishments
  - Implemented and explored Cedille-Core, a minimal proof language designed by Aaron Stump.
  - Based on it, developed a 800 LOC type-theory compatible with optimal reductions,
    previously called Formality, which we now call Elementary Affine Type Theory (EA-TT).
  - Based on Symmetric Interaction Combinators, developed Elementary Affine Net
    (EA-Net), an interaction net system and compile target for EA-TT.
  - [Stated and proved several theorems on EA-TT](proofs and libraries), to validate
    and explore its expressivity.
    Wrote a blog post introducing it.
  - Started working on the Moonad Operating System, bu
    t stopped to focus in developing an efficient proof language.
  - Started a compiler to the EVM.
  - Developed a HTML/JS animation tool for EA-Net.

2019 Q2 Accomplishments
  - Developed Elementary-Affine-Core (EA-TT), the untyped version of EA-TT.
  - Restructured Formality (the typed proof language) into many sub-projects:
  - Wrote several FM-Core libraries, including:
  - Finished the EA-Net-˃EVM compiler. Still needs optimizations. FM-Net next.
  - A prototypal C-backend for FM-Net. (Soon we'll have C++/LLVM experts optimizing it!)
  - Wrote a Github Wiki for Formality-Core.

Current Status (updated: June 22, 2019)
  - focus in graduating from the EF and creating our own company.
   ... Our mission will be to develop Formality as an efficient,
       user-friendly proof language suitable to write smart-contracts,
       graphical applications, servers and so on ...
mythril
@[https://github.com/ConsenSys/mythril/wiki]
  Mythril detects a range of security issues, including
  integer underflows, owner-overwrite-to-Ether-withdrawal,
  and others. However, the analysis will not detect business
  logic issues and is not equivalent to formal verification.
Sec.Tool Index
(consensys)
@[https://consensys.github.io/smart-contract-best-practices/security_tools/]
ºVisualizationº
 - Sūrya tool for smart contract systems,
    offering a number of visual outputs and information about the contracts' structure.
    Also supports querying the function call graph.
 - Solgraph generates a DOT graph
   that visualizes function control flow of a Solidity contract and highlights potential
   security vulnerabilities.
 - EVM Lab: Rich tool package to interact
    with the EVM. Includes a VM, Etherchain API, and a trace-viewer.
 - ethereum-graph-debugger
    A graphical EVM debugger. Displays the entire program control flow graph.

ºSTATIC AND DYNAMIC ANALYSISº
  - Mythril Classic - Swiss army knife for smart contract security.
  - Slither - Static analysis framework with detectors for many common Solidity issues. It has taint and value tracking capabilities and is written in Python.
  - Echidna - The only available fuzzer for Ethereum software. Uses property testing to generate malicious inputs that break smart contracts.
  - Manticore - Dynamic binary analysis tool with EVM support.
  - Oyente - Analyze Ethereum code to find common vulnerabilities, based on this paper.
  - Securify - Fully automated online static analyzer for smart contracts, providing a security report based on vulnerability patterns.
  - SmartCheck - Static analysis of Solidity source code for security vulnerabilities and best practices.
  - Octopus - Security Analysis tool for Blockchain Smart Contracts with support of EVM and (e)WASM.

ºWEAKNESS OSSCLASSIFCATION & TEST CASESº
 - SWC-registry - SWC definitions and a large repository of crafted and real-world
   samples of vulnerable smart contracts.
 - SWC Pages - The SWC-registry repo published on Github Pages


ºTEST COVERAGE:º
- solidity-coverage - Code coverage for Solidity testing

ºLINTERS:º
 - Solcheck
   A linter for Solidity code written in JS and heavily inspired by eslint.
 - Solint
   Solidity linting that helps you enforce consistent conventions and avoid errors in your Solidity smart-contracts.
 - Solium
   Yet another Solidity linting.
 - Solhint
   A linter for Solidity that provides both Security and Style Guide validations.
Security Best Practices
@[https://consensys.github.io/smart-contract-best-practices/]
fixing
"stack too deep"
error
@[https://blog.aventus.io/stack-too-deep-error-in-solidity-5b8861891bae]
Alex Pinto (2019-01)
- error generated when the code needs to access a slot in the stack frame deeper than its 16th element 
  (counting from the top downwards). 


    FUNCTION 
  STACK FRAME
  -----------
- local var3
- local var2
- local var1
...
- input  arg3
- input  arg2
- input  arg1
- 'return address' ← where to return from function

- There are too many ways in which it can be triggered.

- So here are some streamlined notes to keep in mind:
  - When a function is called, a stack frame is created. This includes, from bottom to top:
  - the function selector
  - the return address
  - the leftmost value-type argument of the function
  - …
  - the rightmost value-type argument of the function
  - “Stack Too Deep” errors depend on the central opcode of an action
    (eg arithmetic, hashing, calling another function, emitting events, etc.)
    If these central operations are performed on pure function arguments,
    the order in which they are passed to the function may decide the occurrence
    of a “Stack Too Deep” error.
    (Stack slots can also be used for intermediate calculations and local variables)
  - It is crucial to know the number and order of the arguments for the opcode.
    These arguments are typically read from the stack 
    (the only exception is the PUSH opcode).
  - Opcode arguments have to be pushed to the stack before executing the opcode.a
   ºEach PUSH moves the function arguments down at least one slotº
  - The function arguments deeper in the stack are the ones that were processed first,
    that is, the leftmost ones in the function signature.
  -ºIf some of the function arguments are not used in that opcode operation,    º
   ºthen they should come first in the function signature, to reduce the chancesº
   ºthat opcode arguments will be off-reach when they need to be stacked.       º

  -ºOpcodes use arguments at different levels in the stack. Deeper levels are pushed first.º
   ºIf an argument is pushed after another, it should appear in the function signature     º
   ºafter the former as well, otherwise it would push the other one down the               º
   ºstack before it could be used.                                                         º
    Example:
    - Consider an event with two indexed arguments [t1, t2] in this order,
      called in a function with several arguments, among which a1 coming before a2
      If the event is emitted with t1 = a1 and t2 = a2, the opcode LOG3 will be called.
      Before calling this opcode, t2 = a2 will be pushed first into the stack.
      This will push a1 down and put it at risk of being unreachable when the time 
      comes to push the value of t1 = a1.
      This would be avoided if a1 came after a2 in the function signature, since it
      would be higher in the stack than a2. Assuming a2 was reachable when it was pushed,
      so would be a1 afterwards.

  - more difficult cases arise when calling
    functions in other contracts or libraries, since the opcodes CALL and DELEGATECALL 
    take 7 or 6 input arguments each, with a lot more possibilities of interaction between
    the opcode and function arguments.

Alexandre Pinto — Blockchain developer at Artos (Aventus Ecosystem Party)

As part of his research, Alex has published papers on Kolmogorov Complexity, Cryptography, Database Anonymization and Code Obfuscation.

Pinto also spent seven years lecturing at the University Institute of Maia
including directing the degree programmes for BSc Computer Science and
Information Systems and Software.

This article was originally posted on his blog.

Since you are here, we would love if you connected with us on Telegram,Reddit, Twitter, Facebook, Youtube, Instagram and LinkedIn.

Also, we have started a LinkedIn Group for ticketing developers/other developers to engage, join us and start a conversation.


Libraries,Tokens,...
Token
 taxonomy
@[https://entethalliance.org/token-taxonomy-initiative/]
ERC20 Token
@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md]
  Standard interface to Fungible Assets Contracts that different wallets will understand out-of-the-box
  ERC20 @ Ethereum WiKi
  Problems with the Standard
  ERC20 compliant wallets
ERC-223
@[https://github.com/ethereum/EIPs/issues/223]
ERC20 token standard is leading to money losses for end users.
The main problem is lack of possibility to handle incoming ERC20 transactions,
that were performed via transfer function of ERC20 token.

If you send 100 ETH to a contract that is not intended to work with Ether,
then it will reject a transaction and nothing bad will happen. If you will
send 100 ERC20 tokens to a contract that is not intended to work with ERC20
tokens, then it will not reject tokens because it cant recognize an incoming
transaction. As the result, your tokens will get stuck at the contracts
balance.
ERC-621
@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-621.md]
ERC 621

ERC-621 is an extension of the ERC-20 token standard. It adds two additional
functions, increaseSupplyanddecreaseSupply. This can increase and decrease
the token supply in circulation. ERC-20 only allows a single token issuance
event. This restricts the supply to a certain amount which can’t be changed.
ERC-621 proposes that totalSupply can be modified
ERC-1155
@[https://blog.enjincoin.io/erc-1155-the-crypto-item-standard-ac9cf1c5a226]
- A standard interface for contracts that manage multiple token types. A single
  deployed contract may include any combination of fungible tokens, non-
  fungible tokens, or other configurations (for example, semi-fungible
  tokens)

- In economics, fungibility is the property of a good or a commodity
  whose individual units are essentially interchangeable.

- Some new blockchain games are now also using the more recent
  ERC-721 Non-Fungible Token standard which allows each unit to be
  a unique collectible item with its own serial number.
  These have become popular in some early blockchain games because
  of the success of CryptoKitties.

- Evolved Token for Mainstream Games
  - Multiplayer Games Have LOTS of Items
    - Runescape has 35,000
    - World of Warcraft has over 100,000 different items!
    - Shooters like Overwatch and Team Fortress 2 each
      have thousands of skins and items.

-ºThe biggest problem with existing token designs is that they    º
 ºrequire deploying a separate contract to the blockchain for eachº
 ºand every item type!                                            º
  - EnjinX, our upcoming blockchain explorer, has logged transfers
    from over 74,000 different tokens deployed on Ethereum since 2015.

- ERC-1155 takes a new approach to defining tokens. Items are now
  stored in a single contract with the minimum possible amount of
  data needed to distinguish the token from other ones.
  The contract state contains configuration data per Token ID and
  all the behavior governing the collection with
 ºAtomic Swaps amongst different itemsº

  Atomic Swap ussage examples:
  - Multi-Transfers
    Imagine checking out your groceries at the store and having
    to buy each item in your cart separately.
    This is how ERC-20 and ERC-721 token transfers work,
    it’s just not efficient.
  - In ERC-1155, you can send any number of items to one or
    multiple recipients in a single transaction. This reduces gas
    and congestion on the Ethereum transaction pool

  - The transfer, approve, melt, and trade functions all take
    arrays as parameters, which let you perform between 100–200
    such operations in a single transaction.

- ERC-20 is limited to fungibles, ERC-721 is limited to contracts
  with individual unique copies of items. The two token types are
  not very compatible or mixable.

  ERC-1155 Crypto Items improve on this by combining the benefits
  of both.
ERC-721 token:
Non fungible
@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md]
- "Deed" token

""" Daniel Uribe from Genobank.io will talk about their mission of building a 
  secure and decentralized P2P Genomic Network on the Ethereum blockchain. 
  He will describe how they are using ERC721 and ERC1155 to record unique 
  genomic variants along with the use of IPFS and proxy re-encryption to allow
  for private and secure sharing of DNA data.
  - ERC721 and ERC1155 for recording and transmitting genomic data
  - Proxy re-encryption to secure data and protect privacy 
  - The Ethereum blockchain to keep track of the informed consents 
"""


ERC-827
@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-827.md]
A extension of the standard interface ERC20 for tokens with methods
that allows the execution of calls inside transfer and approvals.
erc-725 Identity
@[https://erc725alliance.org/]
ERC-725 Identity Std: TODO:
@[https://erc725alliance.org/]
- What is ERC 725?
  ERC 725 is a proposed standard for blockchain-based identity
  authored by Fabian Vogelsteller, creator of ERC 20 and Web3.js. ERC
  725 describes proxy smart contracts that can be controlled by
  multiple keys and other smart contracts. ERC 735 is an associated
  standard to add and remove claims to an ERC 725 identity smart
  contract. These identity smart contracts can describe humans, groups
  , objects, and machines. ERC 725 lives on the Ethereum
  blockchain.


- Why ERC 725?
  ERC 725 allows for self-sovereign identity. Users should be able to
  own and manage their identity instead of ceding ownership of
  identity to centralized organizations. We have seen the negative
  effects of having centralized identity with damaging leaks and
  unfair selling of user data and identity. An open, portable
  standard for identities will enable decentralized reputation,
  governance, and more. Users will be able to take their identity
  across different Dapps and platforms that support this standard.
Ex:Minimun
Signature number
@[https://gist.githubusercontent.com/mingderwang/33994fddda49a45671e093b321912cbd/raw/eeec75f34f1b311d88337f2e0ce6d8fa58ed175a/wallet.sol]
Inheritable "property" contract:
ºenables methods to be protected by requiring the acquiescence of either aº
ºsingle, or, crucially, each of a number of, designated owners.º
// REF: Wallet.sol gist
// @authors: Gav Wood ˂g@ethdev.com˃
contract multiowned {
    struct PendingState { uint yetNeeded; uint ownersDone; uint index; }
    mapping(bytes32 /* operation_hash */ =˃ PendingState) OºmapPendingOpsº; // ongoing ops
    uint public minimum_required; // minimum owners confirmations for same operation

    mapping(address =˃ uint /*Qºbit idxº*/) QºmapOwner2Idxº; // ºallow reverse lookupº
    bytes32[] m_pendingIndex;

    modifier onlyOwner { if (QºmapOwner2Idxº[msg.sender] == 0) throw ; _ }

       /* same operation hash must be signed/accepted by a minimum number
        * of the set of owners (specified in the constructor) before execution */
      ºmodifier  BºonlyMany/*¡¡SIGNATURE!!*/Ownersº(bytes32 _operation_hash) {º
      º if (!BºconfirmAndCheckº(_operation_hash)) throw ;  _ }º

      ºconstructor(address[] _owners,º // ← "who" can confirm,
      *    uint minimum_required { // ← minimum. confirmations
        QºmapOwner2Idxº[msg.sender] = 1;
        for (uint i = 0; i ˂ _owners.length; ++i)
            { QºmapOwner2Idxº[_owners[i]] = 2 + i; }
        minimum_required = minimum_required;
    }

    function ºhasConfirmed(bytes32 _operation_hash, address _owner)º constant returns (bool) {
        var pending = OºmapPendingOpsº[_operation_hash];
        uint ownerIndex = QºmapOwner2Idxº[_owner];
        uint GºownerIdxBitº = 2ººownerIndex; // determine bit to set
        return (pending.ownersDone ⅋GºownerIdxBitº == 0) ? false : true;
    }

    function BºconfirmAndCheckº(bytes32 _operation_hash) internal returns (bool) {
        uint ownerIndex = QºmapOwner2Idxº[msg.sender]; // get idx for msg.sender
        var pending = OºmapPendingOpsº[_operation_hash];
        if (pending.yetNeeded == 0) {
            pending.yetNeeded = minimum_required; // reset confirmations needed
            pending.ownersDone = 0; // reset owners confirmed to none (bitmap→0)
            pending.index = m_pendingIndex.length++;
            m_pendingIndex[pending.index] = _operation_hash;
        }
        uint GºownerIdxBitº = 2ººownerIndex; // determine the bit to set
        if (pending.ownersDone ⅋ GºownerIdxBitº == 0) {
            // ok - check if count is enough to go ahead.
            if (pending.yetNeeded ˂= 1 /* enough confirmations. reset→run*/) {
                delete m_pendingIndex[OºmapPendingOpsº[_operation_hash].index];
                delete OºmapPendingOpsº[_operation_hash];
                return true;
            } else {
                pending.yetNeeded--;
                pending.ownersDone |= GºownerIdxBitº;
                return false;
            }
        }
    }
}
Voting
@[https://github.com/ethereum/go-ethereum/wiki/Contract-Tutorial]
contract Voting {
  uint       public OºMIN_QUORUMº  ;
  uint       public OºDEBATING_PERIODº ;
  address    public GºFOUNDERº        ;
  Proposal[] public proposals      ;
  uint       public numProposals   ;

  struct BºVote     { int UpOrDown; address voter; }º
  struct Proposal {
    BºVote[]  votesº      ; mapping (address =˃ bool) voted;
    bytes32 data        ; string  description;
    uint    creationDate; bool    active     ;
    boolean result;
  }

  constructor(uint _minimumQuorum, uint _debating_period) {
    GºFOUNDERº          = msg.sender;
    OºMIN_QUORUMº      = _minimumQuorum || 10;
    OºDEBATING_PERIODº = _debating_period * 1 minutes || 30 days;
  }

  function newProposal(bytes32 _data, string _descrip) returns (uint YºproposalIDº) {
      YºproposalIDº     = proposals.length++;
      Proposal p     = proposals[YºproposalIDº];
      p.data         = _data;
      p.description  = _descrip  ;    p.creationDate = now;
      p.active       = true      ;    numProposals   = YºproposalIDº+1;
  }

  function vote(uint _YºproposalIDº, int _UpOrDown /*+1|-1*/) returns (uint QºvoteIDº){
      if (_UpOrDown ˂ -1 ⅋⅋ _UpOrDown ˃ 1 ) revert("UpOrDown is not valid") ;
      Proposal p = proposals[_YºproposalIDº];
      if (p.voted[msg.sender] == true) return;
      QºvoteIDº = p.Bºvotesº.length++;
      p.Bºvotes[QºvoteIDº] = /*new*/Vote({UpOrDown: _UpOrDown, voter: msg.sender})º;
      p.voted[msg.sender] = true;
  }

  function executeProposal(uint _YºproposalIDº) returns (int Qºresultº) {
      Proposal proposal = proposals[_YºproposalIDº];
      if (/*timeout?*/ now ˃ (proposal.creationDate + OºDEBATING_PERIODº) && proposal.active){
          uint quorum = 0;
          for (uint i = 0; i ˂  proposal.Bºvotesº.length; ++i) {
              Vote v = proposal.Bºvotesº[i];
              quorum += 1;
              Qºresultº += v.UpOrDown;
          }
          if (quorum > OºMIN_QUORUMº) {
              proposal.active = false;
              proposal.result = result >=0 ? true : false;
          }
      }
  }
}
Libraries
About Libraries:
@[https://blog.aragon.one/library-driven-development-in-solidity-2bebcaf88736]
Library benefits:
  - saving substantial amounts of gas
  - can make for a more secure environment (if reused libraries are audited).

- In Solidity, a library is a different type of contract
  (library myLib {...} vs contract myContract {...}) ,
  doesn't have any storage and cannot hold ether:
  - It doesn't allow payable functions and cannot have a
    fallback function, enforced by the compiler.

- It can be seen as a sort of a singleton in the EVM:
  a piece of code that can be called from any contract
  without the need to deploy it again.

- It can also be seen as implicit base contracts of
   the contracts that use them

- EVM DELEGATECALL instruction is used to call the function,
  causing the calling context to be passed to the library,
  as if it was code running in the contract itself.

  context kept by library:
  | this       ← address of the contract invoquing the library not the
  |              library context
  | msg.sender ← sender address sing
  | msg.value
  | msg.sig
  | msg.data
  | msg.gas

 - Library ºlinkingº happens at the bytecode level (compile
   phase) and not at storage level so once setted it's lined
   for always:

   When contract A is compiled, it leaves a Oºplaceholderº for
   the library address in this way:

    0073Oº__ºCOº_____________________________________º630dbe671f
        Oº  ºCOº                                     º  ^^^^^^^
        Oº  ºCOº                                     º  0dbe671f is the function
        Oº  ºCOº                                     º  signature for a()

    * At compile time (before deploying the contract) the placeholder must be
      replaced with the address of the deployed library in the blockchain.


PROBLEM With Events sent by Libraries:
  Only problem is, right now (March 2017), the contract ABI does
  not reflect the events that the libraries it uses may emit.
   This confuses clients such as web3, that won't be able to
  decode what event was called or figure out how to decode its
  arguments.

HACK:  defining the event both in the contract and the library
  will trick clients into thinking that it was actually the
  main contract who sent the event and not the library.

See also:
Awesome Sol.Libs
Decompiling
mainnet Contracts
@[https://www.contract-library.com/]
- Decompiles most smart contracts deployed on the mainnet to a high level representation.
EIP-1538
Upgradeable
Contracts

@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1538.md]
- This standard provides a contract architecture that makes upgradeable 
  contracts flexible, unlimited in size, and transparent.
- A transparent contract publicly documents the full history of all changes
  made to it.
- All changes to a transparent contract are reported in a standard format.
Open Zepellin
OZ Summary
@[https://github.com/OpenZeppelin/]
- TODO: Summary of "important" libraries

OZ 2.0 API
@[https://openzeppelin.org/api/docs/access_Roles.html]

Roadmap:
- @[https://medium.com/zeppelin-blog/zeppelin-framework-proposal-and-development-roadmap-fdfa9a3a32ab#.xk3bv3cw8]
O.Zepelling RBAC
@[https://openzeppelin.org/api/docs/ownership_rbac_RBAC.html]
Upgradable Contracts
REFS:
- @[https://www.youtube.com/watch?v=FzmzUHLiutg] Elena Nadolinski presentation
  TODO: Check diagram at 6m:32sec.
- @[https://blog.zeppelinos.org/getting-started-with-zeppelinos/]
- @[https://paulrberg.com/post/2018/12/30/upgradeable-smart-contracts/]

ZeppelinOS "zos" is a command line tool to makes writing upgradeable contracts extremely easy, abstracting away the complexities of upgradeability.
 It is based on proxy libraries as explained [here]

WARN: Upgradeability can NOT be applied to already-deployed contracts.

ºzos installº
$ npm install --global zos

ºzos ussageº
$ mkdir zos-demo ⅋⅋ cd zos-demo
$ npm init -y
$ zos init zos-demo  # create the zos.json config. file
                                  ^^^^^^^^
                              config file that makes zos
                              aware of your smart contract
                              architecture.

$ npm install --save zos-lib # A "contracts" folder is created

$ vim contracts/CounterContract.sol
 pragma solidity ^0.4.21;
 import "zos-lib/contracts/migrations/Migratable.sol";

 | contract CounterContract is Migratable {
 |
 |   uint256 public counter;
 |
 |   // ºinitialize replaces constructor in upgradable contractº
 |   // guaranting that the new contract version can only be initialized once.
 |   function Oºinitializeº(uint256 _counter)
 |     // isInitializer takes the name of contract and version ID
 |     ºisInitializer("CounterContract", "0")º public {
 |     counter = _counter;
 |   }
 |
 |   function increment() public {
 |     counter += 1;
 |   }
 | }
 |
 Note: If you do use a constructor in an upgradeable smart contract,
       everything you set in the constructor will be ignored.


ºTestingº
("npm install --save ganache-cli" if not already done)
$ npx ganache-cli --port 9545

$ zos add CounterContract  # ← STEP 1: Add smart contract to zos
$ zos push --network local # ← STEP 2: push it to the local network:

$ zos create CounterContract \ # create&initialize upgradeable instance
      --init Oºinitializeº \
      --args 42 \     ← must match the Oºinitializeº method.
      --network local
→ ...
→ ... GºCounterContract proxy: ˂address˃º  ← address to use for instance
→ ...                                                  (safe somewhere safely!)

$ npx truffle console --network=local  # ← enter truffle interactive console
  truffle˃ counterContract = CounterContract.deployed()    # Alt 1:
  truffle˃ counterContract = CounterContract.at("address") # Alt 2:
  truffle˃ counterContract.increment()                     # Call public method
  truffle˃ counterContract.counter().then(counter =˃ counter.toNumber()) # Fetch value
  → 43
  truffle˃ .exit

ºUpgrade deployed contractº
  (add incrementByTwo and history map)

    pragma solidity ^0.4.21;
    import "zos-lib/contracts/migrations/Migratable.sol";

    contract CounterContract is Migratable {
     uint256 public counter;
 +  mapping(uint256 =˃ address) public history;
    ...

 +  function incrementByTwo() public {
 +     counter += 2;
 +     history[counter] = msg.sender;
 +   }
    }
RºWARN: When writing new versions of your contract, you must preserve all variables thatº
Rº      appear in previous versions of your smart contract in the same order.           º
Rº      You should only make additive changes.                                          º

$ zos push --network local                    # ← Push new version.
$ zos update CounterContract --network local  # ← update CounterContract to new version

ºTest new versionº
$ npx truffle console --network=local to access the truffle console.
   truffle˃ counterContract = CounterContract.deployed() # alt 1
   truffle˃ counterContract = CounterContract.at("address")
   truffle˃ counterContract.incrementByTwo()
   truffle˃ counterContract.counter().then(counter =˃ counter.toNumber())
   → 45
   truffle counterContract.history(45)
   → 0x....

ºNote: If at any point you’ve stopped Ganache and need to restart this process all over,  º
ºmake sure you delete zos.local.json file as well. This isn’t a problem for other networksº 
ºsince typically networks don’t get wiped out :)º
ZOS TODO
Getting Started with Z.OS
Mainnet Deploy
Advanced Tutorial
Advanced example (Crafty)
Related
https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2
https://blog.colony.io/writing-upgradeable-contracts-in-solidity-6743f0eecc88
https://blog.indorse.io/ethereum-upgradeable-smart-contract-strategies-456350d0557c
blockapps
@[https://github.com/blockapps]
Advanced
deployment
@[https://blog.aragon.one/advanced-solidity-code-deployment-techniques-dc032665f434]

Upgradeability
@[https://hack.aragon.org/docs/apm.html]
- As a DAO, each aragonPM registry includes a number of installed applications,
  including one APMRegistry, one ENSSubdomainRegistrar, and many Repo instances.
AragonOS
@[https://hack.aragon.org/docs/aragonos-intro.html]
aragonOS provides the following functionality:
- DAO: Decentralized Autonomous Organization

- Upgreadability: Smart contracts can be upgraded to a newer version. 
   Example: fixing a bug or adding a feature.
- Permission control: By using the auth() and authP() modifiers you can 
  protect functionality such that they're only accessible by other apps or 
  entities if given permission. This completely abstracts the authentication 
  logic from an app, allowing you to focus on your app's business logic. 
  Example: protecting a vault so only the organization's Voting app can 
  initiate an action to transfer funds.
- Forwarders: aragonOS apps can communicate with each other by sending their 
  intent to perform an action to other apps. Example: withdrawing funds from 
  a vault only on the passing of a vote and the expiring of a time-lock.

- All the above makes it very simple for aragonOS apps to incorporate governance.
  You just need to add a voting app, configure permissions the right way, and 
  away you go!
Aragon Apps
@[https://github.com/aragon/aragon-apps]
This repository contains the following apps:
 - Vault       : Securely owns and manages tokens on behalf of a DAO.
 - Finance     : Send payments and manage expenses with budgeting.
 - Voting      : Create votes that execute actions on behalf of token holders.
 - Token Manager: Manages organization tokens.

Under development:
 -  Payroll    : Manages employees' payrolls.
Modular-Network Libs
@[https://github.com/modular-network/ethereum-libraries]
- ArrayUtilsLib
- BasicMathLib
- CrowdsaleLib
- LinkedListLib
- StringUtilsLib
- TokenLib
- VestingLib
- WalletLib
Deprecated libs:
Dapp-bin
Amongst others contains
   linkedList.sol and iterable_mapping.sol but it's not maintained since Mid-2017
Development Tools
External Links
@[http://ethereum.stackexchange.com/questions/269/what-exactly-is-an-ethereum-client-and-what-clients-are-there/335]
@[https://www.reddit.com/r/ethdev/comments/9jw839/long_list_of_ethereum_developer_tools_frameworks/]
Remix IDE
@[https://remix-ide.readthedocs.io/en/latest/]
@[https://medium.com/remix-ide/remix-ide-renewal-release-0-8-4a55da933b70]
MetaMask Plugin
@[https://metamask.github.io/metamask-docs/]
- browser extension enabling browsing Ethereum blockchain enabled websites.
- Injects a web3 provider into the window object of the web page.
- It handles account management, ethereum client-node managements,
- Allows users to manage accounts and their keys in a variety of ways,
  including hardware wallets, while isolating them from the site context.
  (vs storing the user keys on a single central server, or even in local storage)
ºAPI Referenceº
./API_Reference/Ethereum_Provider ← "web3 provider object"
./API_Reference/JSON_RPC_API
./API_Reference/Experimental_APIs

ºCalling a Contract from Web Browser with Metamask and ethjsº
@[https://medium.com/metamask/calling-a-smart-contract-with-a-button-d278b1e76705]
(ethjs is a lightweight alternative to web3.js)
- ethjs (or web3.js) makes use of a web3 provider object.
  This object can be a software object, and injected object (Metamask),
  ....

PRE-SETUP:
$ npm install ethjs

BASIC JS:
// "Webpack dependencies"
const Eth = require('ethjs-query')
const EthContract = require('ethjs-contract')
const CONTRACT_ADDRESS = '0xdeadbeef123456789000000000000'
const CONTRACT_ABI = [{
    "name": "transfer",
    "inputs": [ ...  ],
    "outputs": [ ... ],
    ...
  }]


function initContract (contract) {
  const MiniToken = contract(CONTRACT_ABI)
  const miniToken = MiniToken.at(address)
}

function startApp(web3) {
  const eth = new Eth(ºweb3.currentProviderº)
                     ^^^^^^^^^^^^^^^^^^^^^^^^
                     Injected into web page by MetaMask
  const contract = new EthContract(eth)
  initContract(contract)
}

window.addEventListener('load', function() {
  if (typeof web3 === 'undefined') { return; }
  startApp(web3);
})



function onGUIButtonCliced (miniToken) {
    miniToken.transfer(
      toAddress, value, { from: addr })
      .then(
        txHash =˃ {
          console.log('Transaction sent')
          console.dir(txHash)
          waitForTxToBeMined(txHash)
        })
      .catch(e =˃ { ... })
}
MetaMask Mobile
@[https://mobile.metamask.io/]
Web3JS API
@[https://github.com/ethereum/wiki/wiki/JavaScript-API]
- See also: etherlime (web3js alt)
@[https://medium.com/limechain/etherlime-framework-8cbb270944d6]

eth_accounts                                           eth_getTransactionCount
eth_blockNumber                                        eth_getTransactionReceipt
eth_call                                               eth_hashrate
eth_coinbase                                           eth_mining
eth_compileSolidity                                    eth_newBlockFilter
eth_estimateGas                                        eth_newFilter (includes log/event filters)
eth_gasPrice                                           eth_sendTransaction
eth_getBalance                                         eth_sendRawTransaction
eth_getBlockByNumber                                   eth_sign
eth_getBlockByHash                                     eth_syncing
eth_getCode (only supports block number “latest”)      eth_uninstallFilter
eth_getCompilers                                       net_listening
eth_getFilterChanges                                   net_peerCount
eth_getFilterLogs                                      net_version
eth_getLogs                                            miner_start
eth_getStorageAt                                       miner_stop
eth_getTransactionByHash                               rpc_modules
eth_getTransactionByBlockHashAndIndex                  web3_clientVersion
eth_getTransactionByBlockNumberAndIndex                web3_sha3
Truffle
"Full Journey"
@[https://www.truffleframework.com/]
ºnew bare Projectº

$ mkdir fibonacci
$ cd fibonacci
$ ºtruffle initº  # ← Create a bare truffle project:
$ vim Smart-Contract contracts/Fibonacci.sol:
    | pragma solidity ^0.4.22;
    | contract Fibonacci {
    |     // fibseries declaration outside function
    |     //   =˃ saved in storage (vs memory)
    |     //    =˃ triggers TX when modified
    |     uint[] fibseries;
    |     // n = how many in the series to return
    |     function generateFib(uint n) public {
    |         // set 1st and 2nd entries
    |         fibseries.push(1);
    |         fibseries.push(1);
    |
    |         // generate subsequent entries
    |         for (uint i=2; i ˂ n ; i++) {
    |             fibseries.push(fibseries[i-1] +
    |                            fibseries[i-2]);
    |         }
    |     }
    | }
$ vim migrations/2_deploy_contracts.js:
WARN: ¡¡¡do not touch 1_initial_migration.js!!!
    | var Fibonacci = artifacts.require("Fibonacci");

    | module.exports = function(deployer) {
    |   deployer.deploy(Fibonacci);
    | };
$ vim truffle-config.js:
    | module.exports = {
    |   networks: {
    |     development: {
    |       host: "127.0.0.1",  ← test geth/ganache/... IP
    |       port: 7545,         ← test geth/ganache/... port
    |       network_id: "*"
    |     }
    |   }
    | };
$ ºtruffle compileº
(compiles /contracts/*.sol → build/contracts/*.json )
JS clients apps can then use the contract with code similar to:
import metacoin_artifacts from '../../build/contracts/MetaCoin.json'

Migrate to default network defined in truffle.js (localhost:8545)
(Ussually this correspond to the testrpc daemon)
$ ºtruffle migrateº
$ vim test/TestFibonacci.js
$ ºtruffle testº

$ ºtruffle deployº Deploy to ""real""/""test"" network
                        # sends contract to the Ethe. network. Will also update
                        # contracts.json adding the {""address"":...""} for the
                        #deployed contract
ºrun multiline scriptº
REF
ºSTEP 1:º Write script to 'myScript.js' file.
ºSTEP 2:º Use require or exec like:
truffle(dev)→ºrequireº('./myScript.js')  ← alt 1:
truffle(dev)→ºexecº './myScript.js'      ← alt 2:
Debug TX
  REF
$ truffle console  # ← Will fail in test node is NOT running
truffle(development)˃ ºcompileº
→ Compiling .\contracts\Fibonacci.sol...
→ Compiling .\contracts\Migrations.sol...
→ Writing artifacts to .\build\contracts
→ ...
( Check for errors)
truffle(development)˃ ºmigrateº
→ Using network 'development'.
→ ...
→ Running migration: 1_initial_migration.js
→ ...
→ Running migration: 2_deploy_contracts.js
→ ...
→ ...
→ ...
→ ...
(Check in geth logs|ganache console that TXs have been mined)

truffle(development)˃ºFibonacci.deployed()º
                     º.then(instance =˃ instance.generateFib(10))º
                               ^^^^^^^^
                               JS "proxy" to
                             newly deployed contract
→ { tx: 'Oº0xf47f...41cº',
→   receipt:
→    { transactionHash: 'Oº0xf47f...41cº',
→      transactionIndex: 0,
→      blockHash: '0x88d45cb84d1f26....49a2ed',
→      blockNumber: 5,
→      gasUsed: 298373,
→      cumulativeGasUsed: 298373,
→      contractAddress: null,
→      logs: [],
→      status: '0x01',
→      logsBloom: '0x000....0000' },
→   logs: []
→ }

truffle(development)˃ console.dir(instance)
→ ...
truffle(development)˃ ºdebugº Oº0xf47f0...1c41cº
→ Gathering transaction data...
→ Addresses affected:
→  0x33b217190208f7b8d2b14d7a30ec3de7bd722ac6 - Fibonacci
→
→ Commands:
→ (enter) last command entered (step next)
→ (o) step over, (i) step into, (u) step out, (n) step next
→ (;) step instruction, (p) print instruction, (h) print this help, (q) quit
→ (b) toggle breakpoint, (c) continue until breakpoint
→ (+) add watch expression (`+:`), (-) remove watch expression (-:)
→ (?) list existing watch expressions
→ (v) print variables and values, (:) evaluate expression - see `v`
→
→ Fibonacci.sol:
→
→ 1: pragma solidity ^0.4.22;
→ 2:
→ 3: contract Fibonacci {
→    ^^^^^^^^^^^^^^^^^^^^
debug(development:0xf47f01da...)˃ ºnº
→ 7:   // n = how many in the series to return
→ 8:   function generateFib(uint n) public {
→      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
→
(Move until reaching the for-loop)
debug(development:0xf47f01da...)˃ ºvº
→         i: 0
→         n: 10
→ fibseries: []
debug(development:0xf47f01da...)˃ º+:{ i, fibseries }º ← watch vars (show after instruction)
                                  º                  º   -:i to unwatch
debug(development:0xf47f01da...)˃ ºoº  ← Repeat until filling the array
→ ...
→ fibseries: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Recompile-Update
truffle(development)˃ ºcompile --allº
                              ^^^^^
                              force recompile all
                              of the contracts.
→ ...
truffle(development)˃ ºmigrate --resetº
→ ...
truffle(development)˃ ºFibonacci.deployed()º
                      º.then(instance =˃ return instance.generateFib(10))º
→ ...
npm pkgs list
@[https://github.com/trufflesuite/truffle/tree/develop/packages]
truffle-artifactor :
truffle-blockchain-utils
truffle-box
truffle-code-utils
truffle-compile-vyper
truffle-compile
truffle-config
truffle-contract-schema
truffle-contract-sources
truffle-contract
truffle-core
truffle-debug-utils
truffle-debugger
truffle-decode-utils
truffle-decoder
truffle-deployer
truffle-error
truffle-expect
truffle-external-compile
truffle-hdwallet-provider
truffle-interface-adapter
truffle-legacy-system
truffle-migrate
truffle-provider
truffle-provisioner
truffle-reporters
truffle-require
truffle-resolver
truffle-sawtooth-seth-provider
truffle-solidity-loader
truffle-solidity-utils
truffle-workflow-compile
truffle
Testing events
@[https://github.com/trufflesuite/truffle/blob/next/packages/truffle-contract/test/events.js#L118-L143]
var assert = require("chai").assert;
var util = require("./util");
describe("Events", function() {
  var Example;
  var accounts;
  var web3;
  var providerOptions = { vmErrorsOnRPCResponse: false };
 ºbeforeº(async function() {
    this.timeout(10000);
    Example = await util.createExample();
    return util.setUpProvider(Example, providerOptions).then(result =˃ {
      web3 = result.web3;
      accounts = result.accounts;
    });
  });
  it('should expose the "on" handler / format event correctly', function(done) {
    Example.new(1).then(example =˃ {
      const event = example.ExampleEvent();
      event.on("data", function(data) {
        assert.equal("ExampleEvent", data.event);
        assert.equal(accounts[0], data.args._from);
        assert.equal(8, data.args.num); // 8 is a magic number inside Example.sol
        this.removeAllListeners();
        done();
      });
      example.triggerEvent();
    });
  });
  it('should expose the "once" handler', function(done) {
    Example.new(1).then(example =˃ {
      const event = example.ExampleEvent();
      event.once("data", function(data) {
        assert.equal("ExampleEvent", data.event);
        assert.equal(accounts[0], data.args._from);
        assert.equal(8, data.args.num); // 8 is a magic number inside Example.sol
        this.removeAllListeners();
        done();
      });
      example.triggerEvent();
    });
  });
  it("should be possible to listen for events with a callback", function(done) {
    const callback = (err, data) =˃ {
      assert.equal("ExampleEvent", data.event);
      assert.equal(accounts[0], data.args._from);
      assert.equal(8, data.args.num);
      done();
    };
    Example.new(1).then(example =˃ {
      example.ExampleEvent(callback);
      example.triggerEvent();
    });
  });
  it("event emitter should fire repeatedly (without duplicates)", async function() {
    let emitter;
    let counter = 0;
    const example = await Example.new(1);
    example.ExampleEvent().on("data", function() {
      emitter = this;
      counter++;
    });
    await example.triggerEventWithArgument(1);
    await example.triggerEventWithArgument(2);
    await example.triggerEventWithArgument(3);
    assert(counter === 3, "emitter should have fired repeatedly");
    emitter.removeAllListeners();
  });
  it("event callback should fire repeatedly (without duplicates)", async function() {
    let counter = 0;
    let duplicate = false;
    const example = await Example.new(1);
    example.ExampleEvent(function(err, res) {
      if (res === false) duplicate = true;
      counter++;
    });
    await example.triggerEventWithArgument(1);
    await example.triggerEventWithArgument(2);
    await example.triggerEventWithArgument(3);
    assert(counter === 3, "callback should have been called repeatedly");
    assert(duplicate === false, "must not fire duplicates as false result");
  });
  it("should listen for `allEvents`", async function() {
    let emitter;
    const events = [], eventNames = [], signatures = ["ExampleEvent", "SpecialEvent"];
    const example = await Example.new(1);
    example.allEvents().on("data", function(data) {
      events.push(data);
      data.event && eventNames.push(data.event);
      emitter = this;
    });
    await example.triggerEvent();
    await example.triggerSpecialEvent();
    assert(
      eventNames.includes(signatures[0]),
      `Expected to hear ${signatures[0]}`
    );
    assert(
      eventNames.includes(signatures[1]),
      `Expected to hear ${signatures[1]}`
    );
    // Make sure we're formattingfor backwards compatibility
    assert.equal(events[0].args._from, accounts[0]);
    assert.equal(events[0].args.num, 8);
    emitter.removeAllListeners();
  });
  it("should `getPastEvents`", async function() {
    const signatures = ["ExampleEvent", "SpecialEvent"];
    const example = await Example.new(1);
    const options = { fromBlock: 0, toBlock: "latest" };
    await example.triggerEvent();
    await example.triggerEvent();
    await example.triggerSpecialEvent();
    await example.triggerSpecialEvent();
    const exampleEvent = await example.getPastEvents("ExampleEvent", options);
    const specialEvent = await example.getPastEvents("SpecialEvent", options);
    assert(exampleEvent.length === 2);
    assert(exampleEvent[0].event === signatures[0]);
    assert(exampleEvent[1].event === signatures[0]);
    // Make sure we're formatting for backwards compatibility
    assert.equal(exampleEvent[0].args._from, accounts[0]);
    assert.equal(exampleEvent[0].args.num, 8);
    assert(specialEvent.length === 2);
    assert(specialEvent[0].event === signatures[1]);
    assert(specialEvent[1].event === signatures[1]);
  });
  // Event signature is:
  // NumberEvent(int numA, int indexed numB, address addrC, uint numD, uint);
  it("should reformat numbers in events to BN by default", function(done) {
    Example.new(1).then(example =˃ {
      const event = example.NumberEvent();
      event.once("data", function(data) {
        const args = data.args;
        assert(web3.utils.isBN(args[0])); // int named
        assert(web3.utils.isBN(args[1])); // int named, indexed
        ...
        assert(web3.utils.isBN(args.numA));
        assert(web3.utils.isBN(args.numB));
        assert(!web3.utils.isBN(args.addressC));
        assert(web3.utils.isBN(args.numD));
        assert(args.numA.toNumber() === 5);
        assert(args.numD.toNumber() === 55);
        this.removeAllListeners();
        done();
      });
      example.triggerNumberEvent(5, 7, accounts[0], 55, 77);
    });
  });
});
test:errors.js          
test:abiV2.js           
test:cloning.js         
test:customoptions.js   
test:deploy.js          
test:deprecated_keys.js 
test:linking.js         
test:methods.js         
test:networkObject.js   
test:networks.js        
test:separation.js      
test:util.js            
  truf.security
@[https://github.com/ConsenSys/truffle-security]
- MythX Security Analysis Plugin for Truffle Framework
- adds automated smart contract security analysis to the
  Truffle framework.
- Compatible with Truffle 4.0 or higher.
web3 v1.0
(migration to)
https://medium.com/@adrianmcli/migrating-your-truffle-project-to-web3-v1-0-ed3a56f11a4

The most popular library for calling into Ethereum smart contracts from the 
Javascript world is Web3.js (repo). In fact, Truffle (the popular Ethereum 
dapp framework) injects this within their own test environment.

Unfortunately, the framework itself (and its official examples) use the 0.20.
x version of Web3.js. And while v1.0 is still technically in beta, more and 
more people are using it because it provides an API that is more explicit and 
is easier to work with (like PromiEvents, I’ll talk about this below)
JAVA
Web3J
@[https://docs.web3j.io/]
pom / gradle dependencies
Example app
Using infura


SYNC. REQUESTS                        | CompletableFuture (Future ON ANDROID): | RXJAVA OBSERVABLE:
Web3ClientVersion web3ClientVersion = | Web3ClientVersion web3ClientVersion =  | web3.web3ClientVersion()
    web3.web3ClientVersion()          |     web3.web3ClientVersion()           |     .observable().subscribe(x -> {
    .send().getWeb3ClientVersion();   |     .sendAsync().get();                |     String clientVersion =
                                      |                  ^blocking             |         x.getWeb3ClientVersion();
                                      |                                        | });


TRANSACT WITH A SMART CONTRACT WRAPPER:       | CALL A SMART CONTRACT WRAPPER:
----------------------------------------------+---------------------------------------------
(changes status in blockchain, needs mining)  | (local query, no mining needed)
TransactionReceipt transactionReceipt =       | Type result =
   contract.someMethod(                       |    contract.someMethod(, ...).send();
     "param1", ...).send();                   |
                                              | The "someMethod" in *.sol contract needs to be
                                              | marked as "view". Otherwise the java wrapper
                                              | will generate code for new TXs returning
                                              | a TX receipt
web3j cli
Wrapper command line client around web3j library:
$ web3j version|wallet|solidity ...
Web3J FILTERS
UUID: 8953db45-cc22-4c14-a104-f8dd688ca096
@[https://docs.web3j.io/filters.html]
- Provide notifications of Ethereum-events
- Based on RXJava
- NOTE: Standard Ethereum filter-classes:
        - Block filters
          - provide only block-hash.
            a second request(block-hash) needed to fetch the actual block
        - Pending TX filters
          - provide only TX-hash.
            a second request(TX-hash) needed to fetch the actual TX
        -ºTopic filtersº (aka SmartContract event-logs):
          - WebSockets
          - JSON-RPC poll

- web3j's managed Filter implementation:
  - Provides a fully asynchronous event based API
    for working with filters.
  - Based on RxJava's Flowables which provides a consistent API
    for working with events, which facilitates the chaining
    together of JSON-RPC calls via functional composition.
    Subscription subscription =
      //Oºstart listening for new eventsº
      web3jº.blockFlowable (false)       º.subscribe(block -˃ { ... }); ← Listening for new blocks
      web3jº.transactionFlowable()       º.subscribe(   tx -˃ { ... }); ← Listening for new mined TXs
      web3jº.pendingTransactionFlowable()º.subscribe(   tx -˃ { ... }); ← Listening for new pending-to-mine TXs
                                                                         (TXs added to local-node queue)
      web3jº.replayBlocksFlowable(blck0, blck1, ˂fullTxObjects˃)º.subscribe(block -˃ { ...  });
      //OºReplay history (block/TX) filters  (in a range blck0 to blck1 of blocks):º
      web3jº.replayBlocksFlowable      (blck0, blck1, ˂fullTxObjects˃)º.subscribe(block -˃ { ... });
      web3jº.replayTransactionsFlowable(blck0, blck1                 )º.subscribe(tx -˃ { ... });
      //OºReplay history (block/TX) filters and provide notification (via the submitted Flowable) once you’ve caught upº
      web3jº.replayPastBlocksFlowable  (blck0,        ˂fullTxObjects˃, ˂onCompleteFlowable˃)º.subscribe(blck -˃ { ... });
                                                                      ^^^^^^^^^^^^^^^^^^^^                    ^^^^^^^
                                                                      listen here for                        listen here for
                                                                      future events                          past events
      //OºReplay history (block/TX) filters and continue listening for new eventsº
      web3jº.replayPastAndFutureBlocksFlowable( block0, ˂fullTxObjects˃).ºsubscribe(block -˃ { ... });
          (.replayPastAndFutureTransactionsFlowable)                                        ^^^^^^^
                                                                                       listen here for
                                                                                       past and future events

      NOTE:simpler alternatives exits providing onley block/tx hashes
   ...
   subscriptionº.unsubscribe()º; ← end subscription

TOPIC FILTERS
 EVM (Smart-Contract) events stored in the TX log of the blockchain.
 - Since code changing the blockchain status (write TXs) are executed
   "at will" (maybe one second later, maybe one hour later) EVM code
   notifies of any return value from calls to smart-contracts functions
   using those events.
   - Note that a solidity function can return a value, but this value
     is just useful to other calling function executed during the TX,
     not to the external web3 client that send the original signed TX
     maybe long time ago. This client only have to oportunity to know
     the TX status by listening for EVM topic log event (filters in web3j)

  STEP 1:
    EthFilter filter = new EthFilter(ºblock0º,ºblock1º, ˂optional-contract-address˃)
                       [º.addSingleTopicº(...) |º.addOptionalTopicsº(..., ...) | ...];
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                     - specify topics of interest and initial/end block.
                     - individual topics represent indexed parameters on the smart contract
                     -ºIf no topics are added, all EVM events taking place in the networkº
                      ºwill be captured.º
  STEP 2:
      Subscription subscription =
        web3jº.ethLogFlowable(filter)º.subscribe(log -˃ { ... });

Java Implementation Note:
- blockFlowable itself is composed of two of separate JSON-RPC calls:

public Flowable blockFlowable(
      boolean fullTransactionObjects, long pollingInterval) {
  // STEP 1: Create flow of block-hash events
  return this.ethBlockHashFlowable(pollingInterval)
    .flatMap(blockHash -˃
      // STEP 2: Map each returned blockHash by using JSON-RPC to query for new block
      web3j.ethGetBlockByHash(blockHash, fullTransactionObjects).flowable()
    );
}


REF:
Integration-Tests
@[https://github.com/web3j/web3j/blob/master/integration-tests/src/test/java/org/web3j/protocol/core/FlowableIT.java]
Manual filter API:
@[https://github.com/web3j/web3j/blob/master/integration-tests/src/test/java/org/web3j/protocol/scenarios/EventFilterIT.java]


fetech receipt logs
@[https://www.programcreek.com/java-api-examples/?class=org.web3j.protocol.core.methods.response.TransactionReceipt&method=getLogs]
private void sendTransferTokensTransaction(...)  {
    Function function = transfer(to, qty);
    String functionHash = execute(credentials, function, contractAddress);
    TransactionReceipt transferTransactionReceipt = waitForTransactionReceipt(functionHash);
    assertThat(transferTransactionReceipt.getTransactionHash(), is(functionHash));
    List˂Log˃ logs = transferTransactionReceipt.getLogs();
    assertFalse(logs.isEmpty());
    Log log = logs.get(0);

    List˂String˃ topics = log.getTopics(); // verify event called with expected function params
    assertThat(topics.size(), is(3));

    Event transferEvent = transferEvent();

    // check function signature - we only have a single topic our event signature,
    // there are no indexed parameters in this example
    String encodedEventSignature = EventEncoder.encode(transferEvent);
    assertThat(topics.get(0), is(encodedEventSignature));
    assertThat(new Address(topics.get(1)), is(new Address(credentials.getAddress())));
    assertThat(new Address(topics.get(2)), is(new Address(to)));

    // verify qty transferred
    List˂Type˃ results = FunctionReturnDecoder.decode(
            log.getData(), transferEvent.getNonIndexedParameters());
    assertThat(results, equalTo(Collections.singletonList(new Uint256(qty))));
}
 
Headlong
@[https://github.com/esaulpaugh/headlong]
- A Contract ABI and Recursive Length Prefix library in Java for use on the Ethereum network

Contract ABI and Recursive Length Prefix made easy in Java (or Android).
Everything heavily optimized for maximum throughput (ABI function call encoding
 ºup to 500x faster than a popular competitorº and one function creation plus one
encode is up to 60x faster ("f(uint,uint32[],bytes10,bytes)", openjdk 11.0.1)).
C#
Nethereum
@[https://nethereum.readthedocs.io/en/latest/]
PRE-SETUP
$ ºdotnet add package Nethereum.Web3º

ºSending Ethersº
using System;
using Nethereum.Web3;
using Nethereum.Web3.Accounts;
using Nethereum.Web3.Accounts.Managed;
using Nethereum.Hex.HexTypes;
using Nethereum.HdWallet;

bool useSoftWallet = true // ← false =˃ Use HW Wallet
if (useSoftWallet) {
  // Alt 1: Use ºprivate key/Software walletº to init web3 instance.
  var account = new Account(
      "0x... 32 bytes- private key in Hex format ");

  var web3 = new Web3(account);
} else {
  // Alt 2: Use ºHW Walletº to init web3 instance
  string Words = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal";
                  string Password = "password";
  var wallet = new Wallet(Words, Password);
  var account = wallet.GetAccount(0);
  var toAddress = "0x13f022d72158410433cbd66f5dd8bf6d2d129924";
  var web3 = new Web3(account);
}
var toAddress = "0x13f022d72158410433cbd66f5dd8bf6d2d129924";

var TXManager = web3.Eth.GetEtherTransferService();
var TX = await TXManager
    .TransferEtherAndWaitForReceiptAsync(
       toAddress, Web3.Convert.ToWei(1));
 // alt: Specify gas amount
 // .TransferEtherAndWaitForReceiptAsync(
 //    toAddress, Web3.Convert.ToWei(1), 2);
Handling Events
@[https://nethereum.readthedocs.io/en/latest/nethereum-events-gettingstarted/]
- Events ("emit" in solidity code) write data to the transaction receipt logs.

...
var  transactionReceipt = await transferHandler.SendRequestAndWaitForReceiptAsync(contractAddress, transfer);
var transferEventOutput = transactionReceipt.DecodeAllEvents();

Contract Filters and Event Logs

- get all changes of the logs (providing a filter message)
- or create filters and retrieve changes which apply to our filter message periodically.

TO ACCESS THE LOGS:
 - CREATE A TRANSFER EVENT HANDLER FOR OUR CONTRACT ADDRESS
 - CREATE AN EVENT DEFINITION.(TransferEventDTO).

var OºtransferEventHandlerº = web3.Eth.GetEvent˂TransferEventDTO˃(contractAddress /* null to retreive all signature-matching-events from any contract */ );
    ^^^^^^^^^^^^^^^^^^^^
var emptyFilter01 = OºtransferEventHandlerº.CreateFilterInput(); // By default from block cero to current block

var allTransferEventsForContract = await OºtransferEventHandlerº.GetAllChanges(emptyFilter01);

var BºfromToIndexFilterInput01º = OºtransferEventHandlerº.CreateFilterInput˂string, string˃(account.Address, receiverAddress2);
var Bº    toIndexFilterInput01º = OºtransferEventHandlerº.CreateFilterInput˂string, string˃(null, receiverAddress2);
var BºtoManyIndexFilterInput01º = OºtransferEventHandlerº.CreateFilterInput(null, new []{receiverAddress2, receiverAddress});
var allEventsFromTo  = await OºtransferEventHandlerº.GetAllChanges(BºfromToIndexFilterInput01º);
var allEventsTo      = await OºtransferEventHandlerº.GetAllChanges(Bº    toIndexFilterInput01º);
var allEventsToMany  = await OºtransferEventHandlerº.GetAllChanges(BºtoManyIndexFilterInput01º);

var GºfromToIndextFilterIDº = await OºtransferEventHandlerº.CreateFilterAsync(fromToIndexFilterInput01);
var allNewEventsFromTo   = await OºtransferEventHandlerº.GetFilterChanges(GºfromToIndextFilterIDº);
Nuget packages
@[https://nethereum.readthedocs.io/en/latest/nugets/]
- Standalone packages targeting Netstandard 1.1, net451, Netstandard 2.0, Netcoreapp 2.1
  and where possible net351 to support Unity3d.
 (Nethereum.Portable deprecated)
Windows:                                Windows/Mac/Linux users
PM ˃ Install-Package Nethereum.Web3     dotnet add package Nethereum.Web3
ºMain Librariesº
Project Source                    Description
Nethereum.Web3                    Web3-RPC, contract inter./deployment/TX, en/de-coding, event filters
Nethereum.Unity
Nethereum.Geth                    Geth support for Admin, Debug, Miner
Nethereum.Quorum
Nethereum.Parity                  Parity  non-generic RPC API support
ºCore Librariesº

Project Source                  Description
Nethereum.ABI                   Encoding/decoding of ABI Types, functions, events of Ethereum contracts
Nethereum.EVM                   Ethereum Virtual Machine API
Nethereum.Hex                   HexTypes for encoding and decoding String|BigInteger...
Nethereum.RPC
Nethereum.JsonRpc.Client
Nethereum.JsonRpc.RpcClient
Nethereum JsonRpc IpcClient
Nethereum.RLP                   RLP encoding and decoding
Nethereum.KeyStore              Keystore generation|en/de-cryption (Web3 Secret Storage definition)
Nethereum.Signer                Nethereum signer library to sign and verify messages,
                                RLP and transactions using an Ethereum account private key
Nethereum.Contracts             Core library to interact via RPC with Smart contracts
Nethereum.IntegrationTesting    Integration testing module
Nethereum.HDWallet              Generates an HD tree of Ethereum compatible addresses from
                                a randomly generated seed phrase (using BIP32 and BIP39)

ºSmart contract API Librariesº
Project Source                  Description
Nethereum.StandardTokenEIP20    Nethereum.StandardTokenEIP20 Service
Nethereum.Uport                 Uport registry library
Nethereum.ENS                   Ethereum Name service library
ºUtilitiesº
Nethereum.Generator.Console     collection of cli utilities to interact with Ethereum/account management
ºTraining modulesº
Project                         Description
Nethereum.Workbooks             Xamarin Workbook tutorials including executable code
Nethereum.Tutorials             Tutorials to run on VS Studio
ºCode templatesº
Source                          Description
Keystore generator              Keystore file generator
Faucet                          Web application template for an Ether faucet
Nethereum Flappy                The source code files for the Unity3d game integrating with Ethereum
Nethereum Game Sample           Sample game demonstrating how to integrate Nethereum with UrhoSharp's
                                SamplyGame to build a cross-platform game interacting with Ethereum
Nethereum UI wallet sample      Cross platform wallet example using Nethereum, Xamarin.Forms and MvvmCross,
                                targeting: Android, iOS, Windows Mobile, Desktop (windows 10 uwp), IoT
                                with the Raspberry PI and Xbox.
Python
Brownie
@[https://eth-brownie.readthedocs.io/en/latest/]
@[https://github.com/HyperLink-Technology/brownie]
- simple python framework for testing, deploying and interacting
  with ethereum smart contracts.
Troubleshooting
ºsolc ºbin output is empty, but there are no compilation warnings:*
PROBLEM:
    Next code compiles "OK" using
    SOLC INPUT               |  SOLC OUTPUT
    -------------------------|--------------------
    pragma solidity ^0.4.8;  |  A.bin  6060604...
    contract A {             |  B.bin  6060604...
      uint public a1;        |
    }                        |
                             |
    contract B ºis Aº { |
      uint8 public b1;       |
    }                        |

RºAdding any constructor to the A contract, and keeping same Bº
Rºgenerates erroneus empty B.bin                              º

SOLUTION:
   solc compiler consider the class abstract and does not generate any
   bin due to some of the following reasons:
    - B will need to provide parent A constructor with a parameter
      contract B is A {
        uint8 public b1;

      B*constructor(address _a) A(_a) {*// or A(0x00112...)
           ...
      Bº}º
      }

    - B does NOT implementsall mehtods of declared interfaces or base clases


ºProblem: Transaction with same hash already imported  error:º
REF.1, REF 2.web3j Gitter
    Solution: This means that the same transaction is sent twice with onley the nonce different.
     Probably it's a client error.
TODO
0xcert.org
@[https://docs.0xcert.org/]
- JavaScript framework library that provides a complete set of
  tools for building powerful decentralized applications (dapps).
- It enables management, digital representation, and ownership verification of
  unique assets such as certificates, artworks, and collectibles.
Yakindu
Eclipse IDE
@[https://yakindu.github.io/solidity-ide/]
@[https://github.com/Yakindu/solidity-ide/issues]
Rºbeta stateº
- Eclipse based (Eclipse Public License)
- context sensitive help and code proposals,
- quick fixes, 
- refactorings,
- templates 
- live validation.
- Code navigation.
- Language Server Protocol planned (Integerate with Atom, VSC, ...)
Scalability
Serenity/Eth v2.0
nomenclature
- REF: @[https://medium.com/alethio/ethereum-2-0-terms-demystified-8398357429d7]
  2019-08-13

-ºBeacon Chainº                                 -ºShardsº
  - one chain to rule them all                    - 1024 of them
  - proof-of-stake chain                          - semi independent chains
  - includes beacon blocks                        - include shard blocks
  - the consensus layer for everything            - periodically the state of the shard blocks 
  - manages validators                              is recorded on the beacon chain through
  - applies rewards and penalties                   crosslinks
  - serves as an anchor point for the shards      - once a block on the beacon chain is finalised,
    through cross-links                             the shard blocks referenced in the included 
                                                    crosslinks are considered finalised
                                                  - each shard has a committee of validators 
                                                    attesting blocks

-ºCrosslinksº                         -ºSlotº                                        -ºEpochº
  - a summary of the shard's state      - period of time in which a block proposer     - a number of slots(64 "now")
  - only reference of the shards in       propose a block for attestation                after which validators are
    the beacon chain                    - slots might be empty                           reshuffled in committees
                                        - slots are filled with attested blocks


-ºValidatorsº                                    -ºBlock Proposersº
  - users that have deposited 32eth in the         - random validators chosen by the beacon 
    validator deposit contract and run a             chain to propose blocks for 
    validator node                                   validation/attestation
  - they can be inactive (don’t run as an          - there will be one block proposer per slot
    actual validator yet), active (validating),      for the beacon chain and one proposer 
    pending (opted into becoming a validator         per slot for each of the shards
    but stuck in the entry queue) and exiting 
    (no longer want to validate and stuck in
    the exit queue)

-ºAttestationsº                       -ºCommitteesº                               -ºETH2 or BETHº
  - votes in regards to the validity    - random groups of validators chosen by     - base currency of beacon chain
    of a shard block or beacon            the beacon chain to attest the validity   - will be obtained initially from 
                                          of blocks (beacon+shard)                    rewards and by locking ETH1 in
                                        - target of minimum 128 validators per        the validator deposit contract
                                          committee

-ºValidator Deposit Contractº
  - smart contract on the POW chain
    (in our case, the Ethereum Mainnet)
  - once ETH1 funds are locked in this 
    smart contract, and event log is emitted
    that should be read by the beacon chain
    and the same amount of ETH2 should be
    allocated to the account, now considered 
    a validator
  - this mechanism might change in the future
  - until phase 2 ends the transfer of ETH1 
    to ETH2 is a one way street, can’t get
    ETH1 back, but there is an escape hatch 
    to sell your stake once transfers 
    between validators become possible

Casper Proof-of-Stake
@[https://media.consensys.net/blockchain-vs-distributed-ledger-technologies-1e0289a87b16]
Ethereum Casper Proof of Stake Consensus

An example of cryptoeconomic incentive layers can also be seen in Ethereum?s 
transition to a proof of stake consensus mechanism via implementations of 
Casper. While proof of work has its own internalized game theoretical 
incentive structure to dissuade participants from commandeering the network, 
the transition to proof of stake has even further internal structures for 
disincentivizing participants from equivocating or trying to create 
alternative instances of the blockchain when encountering forks. The staking 
protocol creates a Byzantine Fault Tolerant environment where Ether would be 
bonded into the consensus mechanism. What this means is that individuals 
would be bound by a fidelity bond to behave honorably within the system.
....

Cosmos and Tendermint
Cosmos is also building an ecosystem that relies on the Tendermint consensus 
mechanism that relies heavily upon Byzantine Fault Tolerance algorithms. The 
platform depends on validators that have similar roles as miners in the 
bitcoin network. The validators have staking tokens called Atoms which are 
used to secure the network via a proof of stake mechanism that relies upon 
the trust generated by the bonded validators. The interplay between the 
players in the ecosystem is also indicative of a game theoretical structure 
where validators can lose their tokens or the tokens delegated to them if 
discovered to be violating the protocol. Due to this bonded deposit design of 
stakeholders within this system, the consensus mechanism allows for an 
incentivization mechanism that secures the network. This security design 
allows for the proper functioning of the Application Blockchain Interface
(ABCI), the Inter-Blockchain Communication protocol (IBC) as well as the 
varying interactions between the Cosmos hub and zones.
....
Serenity shards
PoA
PoA: Proof of Authority consensus
@[https://www.mattbrill.com/2019/02/21/getting-started-with-the-gorli-testnet/]
Plasma
Plasma.io
@[https://plasma.io/]
Authors: Joseph Poon and Vitalik Buterin
- framework for incentivized and enforced execution of smart contracts which
is scalable to a significant amount of state updates per second (potentially
billions) enabling the blockchain to be able to represent a significant
amount of decentralized financial applications worldwide. These smart
contracts are incentivized to continue operation autonomously via network
transaction fees, which is ultimately reliant upon the underlying blockchain
(e.g. Ethereum) to enforce transactional state transitions.
_____________________________

https://plasma.io/plasma.pdf
The orchestrated transaction processing paradigm using the interplay between
rootchains, plasma chains, and child chains through a combination of fraud-
proof mechanism designs and fidelity bond incentive structures help satisfy
dynamics between the block-withholding and mass withdrawal surfaces. It also
allows for further cryptoeconomic structures to be filled using mechanisms
from systems like Casper or Truebit for mirroring concepts used in erasure
coding in terms of the data availability problem that is prevalent in the
space. For a multichain architecture, Ethereum would be able to combine the
database coordination and throughput capabilities of a distributed database
system with the public chain compatible capabilities of an actual blockchain.
_____________________________

https://media.consensys.net/blockchain-vs-distributed-ledger-technologies-1e0289a87b16
Through technical evaluations of tools like Plasma and formats of obtaining
consensus in Casper, it is apparent that database management tools like
MapReduce and Abstract Rewrite Systems will be implemented in Ethereum. In
Plasma, MapReduce is an integral part of assembling the coordination of an
account based system and a bitmap-UTXO commitment structure of a multichain
setup.
  ...
Plasma shares quite a bit of influence from a heavily cryptoeconomic
incentive structure focused platform called Truebit which was designed to
increase the offchain computational capabilities of the Ethereum network. By
architecting the Truebit system around a verification game in which Solvers
of the overall consensus mechanism can be challenged by Verifiers which
obtain a reward if they identify a nefarious counterparty, an internal
cryptoeconomic ?checks and balances? of the system is created to incentive a
dominant strategy of behaving fairly. As Plasma through the influence of
TrueBit is focused on creating a multichain interoperability network, the
internal enforcement of the system is paramount toward achieving information
and consensus fidelity.

Plasma Chamber Framework
@[https://github.com/cryptoeconomicslab/plasma-chamber]
- DApps dev framework that guarantees security, scalability, and usability
  utilizing Plasma technology. https://www.cryptoeconomicslab.com/
Lead DAO
@[https://leapdao.org/]
- More Viable Plasma design with smart contract like functionality.
Parity Polkadot
Summary
(web3 project for interoperable chains) 
Enterprise Integration
  Integration Layout
REF: https://medium.com/@bibryam/enterprise-integration-for-ethereum-fa67a1577d43
____________________________________________________________________________________________

ºAPPLICATIONSº

  DAPPS            +------------------+  +-----------------------------+
                   |   Applications   |  |  Explorers, Monitoring ⅋ BI |
                   +------------------+  +-----------------------------+

  INFRA CONTRACTS  +--------+  +----+*4 +----------+    +--------+  +------------+
  ⅋ STANDARS       |IDENTITY|  |RBAC|   |NETWORK   |    |TOKEN   |  |ETHEREUM    |
                   +--------+  +----+   |GOVERNANCE|    |STANDARS|  |NAME SERVICE|
                                        +----------+    +--------+  +------------+
____________________________________________________________________________________________

ºTOOLINGº

  Permisions ⅋     +-------+2  +--------------+2     +---+3   +-----------------------------+3
  Credentials      |WALLETS|   |KEY MANAGEMENT|      |HSM|    |PERMISSIONING/AUTHENTICATION |
                   +-------+   +--------------+      +---+    +-----------------------------+

  INTEGRATION⅋     +-----------+2                    +--------------------------+3 +--------+3
  DEPLOYMENT       |INTEGRATION|                     |ENTERPRISE MANAGEMENT SYS.|  |ORACLES |
  TOOLS            |LIBRARIES  |                     +--------------------------+  +--------+
                   +-----------+

                   +--------+2   +-----------+2
  CLIENT           |JSON|RPC|    |INTER-CHAIN|
  INTERFACES       +--------+    +-----------+
____________________________________________________________________________________________

ºPRIVACYº
                  +--------+2    +--------------------+3  +-------------------+3
                  |ON|CHAIN|     |PRIVATE|TRANSACTIONS|   |OFF+CHAIN          |
                  +--------+     +--------------------+   |(TRUSTED EXECUTION)|
                                                          +-------------------+
____________________________________________________________________________________________

ºSCALINGº
                  +-----------------+2       +------------------+2
                  |ON+CHAIN(LAYER 2)|        |OFF+CHAIN(COMPUTE)|
                  +-----------------+        +------------------+

____________________________________________________________________________________________
ºCORE BLOCKCHAINº

  STORAGE/LEDGER  +------------+      +--------+      +---------+2       +-------------+3
                  |ON+CHAIN    |      |ON+CHAIN|      |OFF+CHAIN|        |ON+CHAIN     |
                  |PUBLIC STATE|      |STORAGE |      |STORAGE  |        |PRIVATE STATE|
                  +------------+      +--------+      +---------+        +-------------+

  EXECUTION       +---+         +-----+2     +-----------+2      +----------+3
                  |EVM|         |SYNC |      |PRECOMPILED|       |TRUSTED   |
                  +---+         +-----+      | CONTACTS  |       | EXECUTION|
                                             +-----------+       +----------+

  CONSENSUS       +---------+             +---------+3
                  |PUBLIC   |             |PRIVATE  |
                  |CONSENSUS|             |CONSENSUS|
                  +---------+             +---------+
____________________________________________________________________________________________
ºNETWORKº

   NETWORK         +------+2         +---------------+3
   PROTOCOL        |DEVP2P|          |ENTERPRISE P2P |
                   +------+          +---------------+

1: Yellow Paper
2: Public     Ethereum
3: Enterprise Ethereum
4: Solidity libraries like Zeppelin allows for RBAC
   fine-grained access into the on-chain smart-contracts
   Standard RBAC in EEA/Quorum expected for mid/late 2019
Alethio,Rakr
(IA auditing)
@[https://aleth.io]
@[https://media.consensys.net/alethio-lighting-up-the-blockchain-with-real-time-stats-a80bb30576db]
@[https://media.consensys.net/using-machine-learning-to-understand-the-ethereum-blockchain-1778485d603a]

_ Alethio's analytics platform helps users visualize, 
  interpret, and react to blockchain data in real time.


""" Current blockchain explorers provide little clarity into the evolving ecosystem.
ºThey are often geared towards developers and leave average users in the dark.º

 How do we access real time block data,ºanalyzing the application layer,º
 detecting anomalies, or monitoring the statistical signals that translate to larger KPIs.
"""

ºUNSUPERVISED LEARNINGº
- find patterns in large data sets.
- reduce complex dataset to simpler high-level patterns/themes.
- By reducing a large dataset into a small number of common themes,
  one can learn what it means for a particular transaction or account
  point to be "normal". (ºanomaly detectionº), or compared to a recent
  historical average (ºnovelty detectionº).
- As of 2019-03 Alethio offers an anomaly detection system for
  TXs, blocks, and accounts.
  - ranking algorithms
  - influence analysis like page rank.

ºSUPERVISED LEARNINGº
- there must be some large initial set of data for which the value
  of the labels or responses is known.
  -ºRakr:º
    - gather external data about accounts (metadata) for the
      purposes of machine learning.
    - Rakr hopes to provide a platform for gathering and sharing
      this valuable metadata.
  - two common subcategories:
    -ºprediction:º
      - use historical data to estimate future value
      - account type:
        - decentralized exchange
        - DOS
        - Ponzi scheme
      - Price prediction (training input: "large set" of historical prices).
    -ºclassification:º
      - use historical data and some given-entity data
        to classify the given-entity. (labeling)

  -  raw data ("the set of knowns") can be used to extract features
     for accounts (total balance, average TX frequency/age/...)

  - Alethio recently added semantic lifting to expand the set of "knowns"
    beyond the protocol layer to include application-level data, such as
    whether a contract is a token, and to which standard it complies.

ºIn Practiceº
Ex: Ponzi model developed by Alethio:
- First model, to expand to more general fraud models in near term.
- feature extraction pipelines built during this model development effort 
  can be reused to classify any account according to one of the labels
  in the (growing) Rakr database. (exchange, art DAO, ICOs, casino, fraud, DoS-alike, ...)
- ... we envision a blockchain where every account and entity is enriched with 
  useful classifications and properties, whether empirical and created by humans,
  or predicted and created by statistical models. 

Keep an eye out for the next article by Paul Lintilhac, which will give an exposition of one of
Alethio’s recent data science initiatives: the Ponzi Model.
Eventeum
@[https://github.com/ConsenSys/eventeum]
Eventeum: listen for specified (SmartContract/Blocks) event emissions
          and broadcasts (Kafka/HTTP/RabbitMQ) them to the middleware layer.

ºFeaturesº: Static/Dynamic Configuration, HA, Resilient to node failures, ºblochain Fork Toleranceº

ºPREREQUISITESº      | ºBUILDº
 - Java 8            |  $ git clone https://github.com/ConsenSys/eventeum
 - Maven             |  $ cd eventeum
 - Docker (optional) |  $ mvn clean package

ºRUNNINGº
 ºAlt 1:ºMongoDB, Ethereum, Zookeeper,           │ºAlt 2:ºDocker                                 │ºAlt 3:ºall-in-one
         Kafka, Rabbit nodes already in place    │ $ cd server ;                                 │ TEST ENVIRONMENT
  $ cd server                                    │ $ºdocker buildº. -t kauri/eventeum:latest     │ $ cd server
  $ export SPRING_DATA_MONGODB_HOST=host..:port  │ $ export SPRING_DATA_MONGODB_HOST=host...:port│ $ docker-compose \
  $ export ETHEREUM_NODE_URL=http://host...:port │ $ export ETHEREUM_NODE_URL=http://host..:port │   -f docker-compose.yml \
  $ export ZOOKEEPER_ADDRESS=zookeeper-host:port │ $ export ZOOKEEPER_ADDRESS=host...:port       │   build
  $ export KAFKA_ADDRESSES=kafka-host:port       │ $ export KAFKA_ADDRESSES=host...:port         │ $ docker-compose \
  $ export RABBIT_ADDRESSES=rabbit-host:port     │ $ export RABBIT_ADDRESSES=host...:port        │   -f docker-compose.yml \
                                                 │                                               │   up
  $Bºjava -jar target/eventeum-server.jar º      │ $Bºdocker run -p 8060:8060 kauri/eventeumº    │
 ────────────────────────────────────────────────┴───────────────────────────────────────────────┴─────────────────────────
 ºCONFIGURING NODESº
(application.yml)
 ethereum:
   nodes:
     - name: default               ← node 1
       url: http://mainnet:8545
     - name: sidechain             ← node 2
       url: wss://sidechain/ws
     - name: sidechain             ← ...
       ...
 eventFilters:                     ←ºHARDCODED EVENTSº
   - id: RequestCreated
     contractAddress: ${CONTRACT_ADDRESS:0x..}
     eventSpecification:
       eventName: RequestCreated
       indexedParameterDefinitions:
         - position: 0
           type: BYTES32
         - position: 1
           type: ADDRESS
       nonIndexedParameterDefinitions:
         - position: 2
           type: BYTES32
     correlationId:
       type: NON_INDEXED_PARAMETER
       index: 0



┌─────────────────────────────────────────────────────────────── ┌──────────────────────────────────────────────────────────
│ ºDYNAMIC REGISTERº                     │ºSUCCESS º             │ ºDYNAMIC UNREGISTERº              │ºSUCCESS º
│ ºREQUESTº                              │ºRESPONSEº             │ ºREQUESTº                         │ºRESPONSEº
│ ───────────────────────────────────────┼────────────────────── │ ──────────────────────────────────┼──────────────────────
│ URL    : /api/rest/v1/event-filter     │Code: 200              │ URL:/api/rest/v1/event-filter/{id}│Code: 200
│ Method : POST                          │Content:               │ Method    : DELETE                │Content: N/A
│ Headers: content-type application/json │ { "id": "id" }        │ Headers   : N/A
│ URL    : -                             │                       │ URL Params: N/A
│ Params                                 │                       │ Body      : N/A
│ Body                                   │
│ {                                      │
│  "id": "event-id",                     │
│  "contractAddress": "0x1...Af4d2",     │
│  "eventSpecification": {               │
│   "eventName": "TestEvent",            │
│                                        │
│   "indexedParameterDefinitions": [     │
│     {"position": 0, "type": "UINT256"},│
│     {"position": 1, "type": "ADDRESS"} │
│   ],                                   │
│   "nonIndexedParameterDefinitions": [  │
│     {"position": 2, "type": "BYTES32"},│
│     {"position": 3, "type": "STRING"}  │
│   ]                                    │
│  },                                    │
│                                        │
│  "correlationIdStrategy": {            │
│    "type": "NON_INDEXED_PARAMETER",    │
│    "parameterIndex": 0 }               │
│ }                                      │





ºBROADCASTEST MESSAGES FORMATº
 (to kafka topic|rabit exch)

SMART-CONTRACT EVENT                        |BLOCK EVENT FORMAT
--------------------------------------------+------------------
{                                           |{
 "id":"unique-event-id",                    | "id":"0x79...",
 "type":"CONTRACT_EVENT",                   | "type":"BLOCK",
 "details":{                                | "details":{
   "name":"DummyEvent",                     |  "number":257,
   "filterId": {SOME_UUID},                 |  "hash":"0x797...",
   "indexedParameters":[                    |  "timestamp":12345678
    {"type":"bytes32","value":"BytesValue"},| },
    {"type":"address","value":"0x00..."}    | "retries":0
   ],                                       |}
   "nonIndexedParameters":[
    {"type":"uint256","value":10},
    {"type":"string","value":"StringValue"}
   ],
   "transactionHash":"0xe4...",
   "logIndex":0,
   "blockNumber":258,
   "blockHash":"0x65...",
   "address":"0x....",
  º"status":"UNCONFIRMED",º
   "eventSpecificationSignature": "0x....",
   "id":"unique-event-id"
 },
º"retries":0º
}

ºCONFIGURATION ENV VARsº
(alternatively use application.yml)
Env Variable                             Default
SERVER_PORT                              8060
ETHEREUM_BLOCKSTRATEGY                   POLL^|PUBSUB
ETHEREUM_NODE_URL                        http://localhost:8545
ETHEREUM_NODE _HEALTHCHECK_PPOLLINTERVAL 2000 (ms)
EVENTSTORE_TYPE                          DB
BROADCASTER_TYPE                         KAFKA^|HTTP|RABBIT
BROADCASTER_CACHE _EXPIRATIONMILLIS      6000000     time that a message should live within eventeum broadcast cache.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ºDuring this time eventeum guarants that duplicate messages are NOT broadcastº
BROADCASTER_EVENT _CONFIRMATION _NUMBLOCKSTOWAIT               12
BROADCASTER_EVENT _CONFIRMATION _NUMBLOCKSTOWAITFORMISSINGTX  200  After a fork, a TX may disappear,
                                                                   This params indicates the number of
                                                                   blocks to wait on the new fork,
                                                                   before assuming that an event emitted
                                                                   during this transaction has been INVALIDATED.
BROADCASTER_MULTIINSTANCE                false      If multiple eventeum instances exits, set this param to true
                                                    so that the eventeum communicates added/removed filters to other
                                                    instances, via kafka.
BROADCASTER_HTTP_CONTRACTEVENTSURL       ...        URL to post to smart-contract events when BROADCASTER_TYPE=HTTP
BROADCASTER_HTTP_BLOCKEVENTSURL                     URL to post to new-blocks     events when BROADCASTER_TYPE=HTTP
ZOOKEEPER_ADDRESS                        localhost:2181
KAFKA_ADDRESSES                          localhost:9092  ← CSV list of addresses
KAFKA_TOPIC_CONTRACT_EVENTS              contract-events   The kafka topic name for broadcast contract event messages
KAFKA_TOPIC_BLOCK_EVENTS                 block-events      The kafka topic name for broadcast block event messages.
KAFKA_REQUEST_TIMEOUT_MS                 20000             The duration after which a request timeouts.
KAFKA_ENDPOINT_IDENTIFICATION_ALGORITHM  null              The endpoint identification algorithm to validate server hostname using server certificate.
KAFKA_SASL_MECHANISM                     PLAIN             The mechanism used for SASL authentication.
KAFKA_USERNAME                           ""                username used to connect to a SASL secured Kafka cluster.
KAFKA_PASSWORD                           ""                password used to connect to a SASL secured Kafka cluster.
KAFKA_SECURITY_PROTOCOL                  PLAINTEXT         Protocol used to communicate with Kafka brokers.
KAFKA_RETRIES                            10                number of times a Kafka consumer will try to publish a message before throwing an error.
KAFKA_RETRY_BACKOFF_MS                   500               The duration between each retry.
SPRING_DATA_MONGODB_HOST                 localhost         mongoDB host (used when event store is set to DB).
SPRING_DATA_MONGODB_PORT                 27017             mongoDB post (used when event store is set to DB).
RABBIT_ADDRESS                           localhost:5672    property spring.rabbitmq.host (The rabbitmq address)
RABBIT_EXCHANGE                          ThisIsAExchange   property rabbitmq.exchange
RABBIT_ROUTING_KEY                       thisIsRoutingKey  property rabbitmq.routingKeyPrefix

(See more info about INFURA Support Configuration in original link)

ºADVANCED CONFIGº

ºKafka Broadcasting Correlation Id Strategiesº
Each subscribed event can have a correlation id strategy association with it,
during subscription.
- A correlation id strategy defines what the kafka message key for a
  broadcast event should be, and allows the system to be configured so that
  events with particular parameter values are always sent to the same
  partition.

- Currently supported correlation id strategies are:
  - Indexed Parameter Strategy: An indexed parameter within the event
    is used as the message key when broadcasting.
  - Non Indexed Parameter Strategy: An non-indexed parameter within the
    event is used as the message key when broadcasting.

ºEVENT STOREº
- Eventeum utilises an event store in order to establish
  the block number to start event subscriptions from,
  in the event of a failover.

- For example, if the last event broadcast for event with id X
  had a block number of 123, then on a failover, eventeum will
  subscribe to events from block 124.

2 supported event store implementations:
  - MongoDB:
    Env Variable             Default    Description
    EVENTSTORE_TYPE          DB         MongoDB event store enabled
    SPRING_DATA_MONGODB_HOST localhost  The mongoDB host
    SPRING_DATA_MONGODB_PORT 27017      The mongoDB post

  - REST Service:
    (see original link for more info)

ºEMBEDDING EVENTEUMº
Eventeum can be embedded into an existing Spring Application
via an annotation following next steps.

STEP 1:  Add Kauri repo to the pom.xml:
  ˂repositories˃
    ˂repository˃
      ˂id˃bintray-consensys-kauri˂/id˃
      ˂url˃https://consensys.bintray.com/kauri˂/url˃
    ˂/repository˃
  ˂/repositories˃

STEP 2: Add eventeum-core dependency to pom.xml:
  ˂dependency˃
    ˂groupId˃net.consensys.eventeum˂/groupId˃
    ˂artifactId˃eventeum-core˂/artifactId˃
    ˂version˃ºLATEST_EVENTEUM_VERSIONº˂/version˃
  ˂/dependency˃

STEP 3: Within your Application class or a
  @Configuration annotated class, add the
  @EnableEventeum annotation.

Known Caveats / Issues
- In multi-instance mode, where there is more than
one Eventeum instance in a system, your services are
required to handle duplicate messages gracefully, as each
instance will broadcast the same events.
Camel Connector
@[https://github.com/bibryam/camel-web3j]
@[https://medium.com/@bibryam/enterprise-integration-for-ethereum-fa67a1577d43]

EXTERNAL STORAGE (IPFS,...)
TODO: Compare with alternative Storage "providers": IPFS , Maidsafe, Storj
- IPFS is just a protocol like http. It is unmotivated (don't have tokens).
- Eris is permissioned blockchain thing and use IPFS underneath.
- Storj, SAFE Network, Sia and Filecoin: motivated storage networks with
  different underlying protocols and design decisions.
- Swarm is an organizational idea. A philosophical structure.
  ""serverless hosting incentivised peer-to-peer storage and content distribution""
  ""From the end user's perspective, Swarm is not that different from WWW,
    except that uploads are not to a specific server. The objective is to peer-to-peer
    storage and serving solution that is DDOS-resistant, zero-downtime, fault-tolerant
    and censorship-resistant as well as self-sustaining due to a built-in incentive
    system which uses peer to peer accounting and allows trading resources for payment.
    Swarm is designed to deeply integrate with the devp2p multiprotocol network layer
    of Ethereum as well as with the Ethereum blockchain for domain name resolution,
    service payments and content availability insurance. """"""

""""""Two major features of swarm that sets it apart from other decentralised
distributed storage solutions (bittorent, zeronet, IPFS) are 'upload and
disappear' and the incentive system. The former refers to fact that Swarm
does not only serve content, but it also provides a cloud storage service.
Unlike related systems, you do not only publish the fact you host content,
but there is a genuine sense in which you can just upload stuff to the swarm
and potentially disappear (drop off as a node, disconnect or just operate
without storage entirely) right away. Swarm aspires to be the generic storage
and delivery service catering for all usecases ranging from serving low
latency realtime interactive web applications as well as acting as guaranteed
persistent storage for rarely used content. The incentive system makes sure
that participating nodes following their rational self interest nontheless
converge on an emergent swarm behaviour that is beneficial for the entire
system as well as economically self-sustaining. In particular, it allows
nodes in the network to pool their bandwidth and storage resources in the
most efficient way to collectively provide services. """""""
here are two kinds of accounts in Ethereum which share the same address space
: External accounts that are controlled by public-private key pairs (i.e.
humans) and contract accounts which are controlled by the code stored
together with the account.
External Inputs
(Oracles)
@[http://ethereumj.io/blog/2015/09/09/friendly-ether-bot/]
MS.Bletchley Cryplets: @[https://azure.microsoft.com/en-us/blog/cryptletsdd/]
ºExample Oracleº
@Override
public void configure() throws Exception {
  from("web3j://http://127.0.0.1:7545?operation=ETH_LOG_OBSERVABLE⅋topics=" + topics)
    .to("log:com.ofbizian.CallbackGetBTCCap?level=INFO⅋showAll=true")

    .setHeader(OPERATION, constant(ETH_SEND_TRANSACTION))
    .setHeader(FROM_ADDRESS, constant("0xc8CDceCE5d006dAB638029EBCf6Dd666efF5A952"))
    .setHeader(TO_ADDRESS, constant("0x484982345fD584a0a16deC5F9ba330f6383af3d9"))
    .process(new Processor() {
      public void process(Exchange exchange) throws Exception {
        int random = rand.nextInt(50);
        Function function = new Function("setBTCCap", Arrays.asList(
          new Uint(BigInteger.valueOf(btcPrice))), Collections.>emptyList());
        exchange.getIn().setHeader(DATA, FunctionEncoder.encode(function));
      }
    })
    .to("web3j://http://127.0.0.1:7545");
}
 Whisper Dapp Protocol
- communication protocol to communicate DApps with each other for off-chain Data.

ºUSE CASE:º
    DApps that need to publish small amounts of information to each other and
have the publication last some substantial amount of time. For example, a
currency exchange DApp may use it to record an offer to sell some currency at
a particular rate on an exchange. In this case, it may last anything between
tens of minutes and days. The offer wouldn't be binding, merely a hint to get
a potential deal started.

    DApps that need to signal to each other in order to ultimately
collaborate on a transaction. For example, a currency exchange DApp may use
it to coordinate an offer prior to creating one (or two, depending on how the
exchange is structured) transactions on the exchange.

    DApps that need to provide non-real-time hinting or general
communications between each other. E.g. a small chat-room app.

    DApps that need to provide dark (plausible denial over perfect network
traffic analysis) comms to two correspondents that know nothing of each other
but a hash. This could be a DApp for a whistleblower to communicate to a
known journalist exchange some small amount of verifiable material and
arrange between themselves for some other protocol (Swarm, perhaps) to handle
the bulk transfer.

*geth experimental flags related to whisper:
  --shh                       Enable Whisper
  --shh.maxmessagesize value  Max message size accepted (default: 1048576)
  --shh.pow value             Minimum POW accepted (default: 0.2)


Whisper Alternative: "Message Contract" and "Telehash"
EtherQuery
@[https://github.com/Arachnid/etherquery]
Custom ethereum client that uploads blockchain data to BigQuery
GraphQL Interface
Extracted from @[https://graphql.org/]
  """GraphQL is a ºquery languageº for APIs and a runtime 
     for fulfilling those queries with your existing data. 
     ... simplifies API evolution, and enable powerful dev
     tools."""

@[https://github.com/ConsenSys/ethql]
(Available in Geth 1.9, Pantheon, probably other implementations)
- Has the potential to avoid the sync from blockchain to a
  conventional SQL database for creating reports.

Example GraphQL Queries
@[https://github.com/ConsenSys/ethql/wiki/Example-Use-Cases]
  ºQuery a single block (5000000)º
[fiddle]
{
  block(number: Bº5000000º) {                        ← Fetch all TXs from block Bº5000000º
    hash
    transactions(filter: Oº{ withInput: true }º) {   ← Oºthat have input dataº
      index
      hash
      from { address }
      to   { address }
      decoded {
        ... on ERC20Transfer {                    ← for those that can be decoded as token transfers, return:
          tokenContract { symbol }                  ← token symbol
          from {                                    ← sending address
            account { address }
            tokenBalance                            ← sending address token balance
          }
          to {                                      ← receiving address
            account { address }
          }
          value
        }
      }
    }
  }
}

ºInformation on specific blocksº
{
  blocks(numbers: [5942631, 5942640, 5927788]) {   ← blocks queried
    transactionsRoles(from:"0xF5b...") {           ← all TXs sent from adress 0xF5b...
      gasPrice                                     ← Return amount of gas expended in each TX
    }
  }
}

ºInformation on a range of blocksº



{
  blocksRange(numberRange: [5400000, 5400005]) {  ← For all 6 blocks between 5400000 and 5400005
    transactions {                                  Return:
      hash
      value
      from {
        address
        balance                                     ←  balance of all addresses that sent a TXs.
      }
      to {
        address
      }
    }
  }
}
ºInformation on an accountº
for account "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d".

{
 account(address: "0x06012..."){ ← For account 0x6012... return:
   storage{
     value(at: 0)                   ← value stored at index 0 in (Solidity Contract) storage
   }
 }
}

ºInformation on a TXº
{
  transaction(hash: "0x7cc...") {   ← For TX with hash 0x7cc... return:
    logs {                          ← fetch the log topics
      topics
      decoded {                     ← and attempt to decode the TX to reveal
        event                         ← event
        entity                        ← entity
        standard                      ← Standard information
      }
    }
  }
}

GraphQL: fetching events
@[https://medium.com/intech-conseil-expertise/create-your-graph-node-to-query-complex-data-from-blockchain-via-graphql-6f08fbd494c5]

- Identity Smart Contract 
  - it stores "claims" == proof of a verification process
    Ex:
    claim type 1: id-holder is French   , attested/signed by issuer_i1
    claim type 2: holder is over 18     , attested/signed by issuer_i1
    claim type 3: has not bank debts    , attested/signed by issuer_i2
    claim type 3: ...                   , attested/signed by issuer_i3
    ...

ºUse-Case 1: Fetch "all claims for a given identity"º

  -RºWrong implementation:º 
    - call .getClaims() on the contract. 
    - Discouraged due to performance and cost issues.
  
  -Gº Correct implementation: Using eventsº
    - Emit ClaimAdded / ClaimRemoved.
    - fetch all logs to rebuild the current array of elements.


ºUse-Case 2: "For each claim type, fetch all claims attested/signedº
             ºby same issuer_iN"º

  -GºImplementation 1, Using events and filters:º
   - fetch all ClaimAdded events filtered by Claim Issuer
   - Repeat for each Identity Contract instance
   - Suboptimal in terms on network bandth ussage. 
     All events are sent back to the client, then the client
     filters the events.

  -GºImplementation 2, Using GraphQL and the Graph protocolº
   GraphQL main advantage is to be able to "traverse" entities,
   minimizing the amount of data sent over the network.

  º"The Graph protocol is a decentralized protocol for       º
  º indexing and querying data from blockchains, starting    º
  º with Ethereum. It makes it possible to query data that isº 
  º difficult to query directly.”                            º


  - Graph features:
     -ºit knows about the entities it indexesº
     - composed of subgraphs, carefully developed by the community
     - There is a global instance of The Graph that accepts 
       subgraph definition.
 
ºSubgraph "Hello World!":º

  - PRE-SETUP
    - An Ethereum node must be running (in http://127.0.0.1:8545 for example)

  -ºSTEP 1º(opinionated, using docker)
    $ git clone https://github.com/graphprotocol/graph-node.git
    $ cd graph-node
    # Update the RPC Server endpoint http://127.0.0.1:8545 if needed 
      in the environment variable @ 'docker-compose.yaml'
    $ sudo docker-compose up # Will start up graph instance, PostgreSQL and IPFS
      ^^^^^^^^^^^^^^^^^^^^^^
      needs ports 4001, 5001, 8000, 8001, 8020, 8080 and 5432  open

  - STEP 2 (opinionated, using nodeJS and yarn)
    $ yarn init                      # ← Init NodeJS project (create 'package.json')

    $ yarn add --dev \               # ← Install graph* NodeJS package dependencies
           @graphprotocol/graph-cli
           @graphprotocol/graph-ts
    $ vim package.json
    {
      "scripts" : {
        "codegen"      : "graph codegen",
        "create-local" : "graph create domain/graph-name --node http://127.0.0.1:8020",
        "build"        : "graph build",
        "deploy-local" : "graph deploy domain/graph-name --debug --ipfs http://localhost:5001 --node http://127.0.0.1:8020/",
        "watch-local"  : "graph deploy domain/graph-name --watch --debug --node http://127.0.0.1:8020/ --ipfs http://localhost:5001"
      }
    }
                                       ^^^^^^^^^^^^^^^^^
                              - Replace domain/graph-name to mirror
                                the SubGraph. Ex: investorid/id 


     $ cp ${ContractABI_json} ./abis        # ← alt 1: Copy ABIs
     $ yarn add --dev @investorid/solidity  # ← alt 2: use a package (prefered)

  -ºSTEP 2:ºCreate 'subgraph.yaml' describing the SubGraph:

    | specVersion: 0.0.3
    | description: Decentralized IDs over Ethereum
    | repository: https://github.com/investorid/investorid-subgraph
    | schema:
    |   file: ./schema.graphql
    | dataSources: []

  -ºSTEP 3:ºCreate 'schema.graphql' describing the entities used
            by the SubGraph and exposed via GraphQL.
    | type Identity @entity {
    |   id: ID!
    |   address: Bytes!
    |   keys: [Key!]! @derivedFrom(field: "identity")
    | }
    | 
    | type Key @entity {
    |   id: ID!
    |   keyType: BigInt!
    |   key: Bytes!
    |   purposes: [Int!]!
    |   identity: Identity!
    | }


Note the custom types added by The Graph, such as BigInt and Bytes. The Graph’s documentation of GraphQL API explains the usage of relationships and specific reverse properties such as @derivedFrom.
(https://thegraph.com/docs/graphql-api)

Note the custom types added by The Graph, such as BigInt and Bytes. The Graph’s documentation of GraphQL API explains the usage of relationships and specific reverse properties such as @derivedFrom.

    Create a file in .src/handlers where the handlers will be implemented mkdir src/handlers/identity.ts.
    Implement the event handlers (let them be no-op for now). Imports for entities and events do not exist yet but will be generated, so ignore any IDE error. The first will come from the schema.graphql file, and the later from the subgraph.yaml definition.

import {
  KeyAdded as KeyAddedEvent,
  KeyRemoved as KeyRemovedEvent,
} from '../../generated/Identity/Identity';

import {
  Identity,
  Key,
} from '../../generated/schema';

export function handleKeyAdded(event: KeyAddedEvent): void {

};

export function handleKeyRemoved(event: KeyRemovedEvent): void {
  
};

Declare the ABI to be used and scanned by the graph node in the subgraph.yaml file.
Any entity used by the event handlers must be declared in the entities property.
A list of all event to be scanned and handled must also be declared in the eventHandlers property. The eventproperty must match the exact event signature contained by the ABI (if an event is not recognized an error will be thrown displaying the list of available events to help for correction).

dataSources:
  - kind: ethereum/contract
    name: Identity
    network: http://localhost:8545
    source:
      abi: Identity
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.3
      language: wasm/assemblyscript
      file: ./src/handler/identity.ts
      entities:
        - Identity
        - Key
      abis:
        - name: Identity
          file: ./node_modules/@investorid/solidity/build/contracts/Identity.json
      eventHandlers:
        - event: KeyAdded(indexed bytes32,indexed uint256,indexed uint256)
          handler: handleKeyAdded
        - event: KeyRemoved(indexed bytes32,indexed uint256,indexed uint256)
          handler: handleKeyRemoved

Now that some entities are defined, generate the typings and the automated code parts that will allow for developing the event handlers: yarn run codegen.
The handler file ./src/handlers/identity.ts should no longer have errors for non-existing imports.

Implementation of event handlers

This is where the fun starts. Time has come to create the event handlers. Refer to The Graph documentation, to learn how to write mappings. Here are the very few basics:

    To create a new entity instance, call #create(). The  is a string that must be generated. To be able to retrieve instances from blockchain data, the IDs should be composed of addresses, hashes, etc...
    To load an existing entity, call #load().
    To save a new entity or persist the update on an existing one, call .save().
    To destroy and remove an entity from the store, call store.remove('EntityName', id) .

I have made an example with Identities that you can access on the InvestorID Organization: github.com/investorid/subgraph-experiment.

Here are the events handlers for the Keys event:
import { log, store, Address, Bytes } from "@graphprotocol/graph-ts";

import {
  KeyAdded as KeyAddedEvent,
  KeyRemoved as KeyRemovedEvent,
} from '../../generated/Identity/Identity';

import {
  Identity,
  Key,
} from '../../generated/schema';

export function handleKeyAdded(event: KeyAddedEvent): void {
  let identity = Identity.load(event.address.toHexString());
  if (identity == null) {
    identity = new Identity(event.address.toHexString());
    identity.address = event.address;

    identity.save();
  }

  let key = Key.load(createKeyID(event.address, event.params.key));
  if (key == null) {
    key = new Key(createKeyID(event.address, event.params.key));

    key.identity = identity.id;
    key.key = event.params.key;
    key.keyType = event.params.keyType;
    key.purposes = [event.params.purpose.toI32()];

    key.save();

    identity.save();
  } else {
    let purposes = key.purposes;
    purposes.push(event.params.purpose.toI32());
    key.purposes = purposes;

    key.save();
    identity.save();
  }
}

export function handleKeyRemoved(event: KeyRemovedEvent): void {
  let identity = Identity.load(event.address.toHexString());
  if (identity == null) {
    return;
  }

  let key = Key.load(createKeyID(event.address, event.params.key));
  if (key == null) {
    return;
  }

  let keyIndex = key.purposes.indexOf(event.params.purpose.toI32());
  if (keyIndex == -1) {
    return;
  }
  let purposes = key.purposes;
  purposes.splice(keyIndex, 1);
  key.purposes = purposes;

  if (key.purposes.length === 0) {
    store.remove('Key', key.id);
  } else {
    key.save();
  }
}

function createKeyID(identity: Address, key: Bytes): string {
  return identity.toHexString().concat('-').concat(key.toHexString());
}

Run our subgraph

    Build the SubGraph with yarn run build ✨
    Declare the SubGraph on the local Graph node yarn run create-local
    Deploy the SubGraph to the local Graph node yarn run deploy-local (there is also a watch start that will deploy the SubGraph after each code update yarn run watch-local. All events will be processed again with the new updated handlers.).
    An GraphQL UI for queries is accessible at http://127.0.0.1:8000/subgraphs/name/domain/graph-name/graphql (replace domain/graph-name by the name of the subgraph). Have fun! Refer to graphQL documentation for queries syntax, especially about filters.

    Note: Whenever the Ethereum network has been reseted (eg. Ganache restarted, computer rebooted…), you must DELETE the ./docker/data folder located in the graph-node folder cloned from the repository).
    This is required to clean the existing database that checks the genesis block for the current ethereum network.

Afterwords

The Graph is an amazing tool that greatly reduces the amount of time required to build an API over blockchain data. The team is even working on historical exploration of the data over time.

I would only recommend to any company having the need to build an intermediary API between blockchain data and its application (not especially Dapp) to give it a try, and to participate in its development. Having an open-source solution that could compete with blockchain explorers that would inevitably come from Amazon, Azure and Google would only benefit the whole community.

The Graph is still young, and I would not be surprised if some breaking change appeared in the incoming months, the documentation is also still in its early stage, with a lack of fully-fledge examples. Yet it’s up to us to improve it, and I hope this article will help toward this direction.





Public Network Clients
Geth
Setup Node
REF
STEP 1 :                              │STEP 2:             │STEP 3: (optional)
──────────────────────────────────────┼────────────────────┼──────────────────
 Create ºgenesis.jsonº                │Initialize node     │Setup bootstrap node
{                                     │(.../qdata/* files) │
  "config": {                         │$ geth Oºinitº\     │$ bootnode --genkey=boot.key
        "chainId": 0,                 │     ºgenesis.jsonº │$ bootnode --nodekey=boot.key
        "homesteadBlock": 0,          ├────────────────────┴────────────────────────────
        "eip155Block": 0,             │
        "eip158Block": 0              │
    },                                │
  "alloc"      : {                    │
  "0x00...01": {"balance": "111111"}, │
  "0x00...02": {"balance": "222222"}  │
  },                                  │
  "coinbase"   : "0x─20 bytes hex─",  │
  "difficulty" : "0x20000",           │
  "extraData"  : "",                  │
  "gasLimit"   : "0x2fefd8",          │
  "nonce"      : "0x0000000000000042",│
  "mixhash"    : "0x ─32bytes hex─",  │
  "parentHash" : "0x ─32bytes hex─",  │
  "timestamp"  : "0x00"               │
}                                     │
──────────────────────────────────────┴

Geth layout:
$DATADIR: (← defined by geth --datadir flag)
 ├─ .ethash/             ← ~1GB dataset used for PoW consensus
 ├─./genesis.json        ← geth init creates initial ddbb based on it
 ├─./qdata/              ← Node Blockchain and state databases, keystore, process log,...
 ├─ ...
 ├─./qdata/geth/nodekey  ← generated automatically on first run or through
 ├─ ...                    'bootnode -genkey .../nodekey' -writeaddress
 ├─./qdata/geth/chaindata/                                ^^^^^^^^^^^^^
 ├─ ...                                                   shows also pub.key
 ├─./qdata/gethLogs/node1.log                             for enode url
 ├─ ...                                                    (optional)
 ├─./qdata/*keystore*/node1key
 ├─./node1.conf
 ├─./keys/node1.key
 ├─./keys/node1a.pub
 ├─./keys/node1.pub
 └─./keys/node1a.key

ºFUll CLI optionsº
@[https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options]
Basic Admin
Geth Account Mng
  º(Geth) ACCOUNT "==" private key stored in file protected by passwordº stored under:
                       $DATADIR/keystore/UTC--'created_at_UTC_ISO8601'-'address hex'

  $ºgeth accountºOºcommandº [options...] [arguments...]
                 Oº^^^^^^^º
                 Oºlist   º
                 Oºnew    º
                 Oºupdate º
                 Oºimport º ← import private key into new account
                              Export key unencryptedºNOTºsupported

  Options:
  --datadir   Base directory for databases and keystore
  --keystore  (defaults to $DATADIR/keystore) Directory for the keystore (default = inside the datadir)

Backup/Restore

$ gethºupgradedbº        ← "Sometimes" the internal database formats need updating
$ gethºremovedbº         ← cleanup: remove blockchain and state databases
                           (does not touch the keystore)
$ gethºexportº'filename' 0 30000 ← Export blockchain in binary format
                         ^^^^^^^
                         initial and
                         final block

$ gethºimportº'filename'         ← Import form binary file

ºGeth extra CLIsº
@[https://github.com/ethereum/go-ethereum/tree/master/cmd]
 abigen
ºbootnodeº   bootnode runs a bootstrap node for the Ethereum Discovery Protocol.
           @[https://godoc.org/github.com/ubiq/go-ubiq/cmd/bootnode]
 clef       ºsigns TXs and dataº. Replacement for acct mgnt
 ethkey      simple tool for working with Ethereum keyfiles

 evm         evm executes EVM code snippets!!.
                - internal/compiler
                - compiler.go
                - disasm.go
                - main.go
                - runner.go
                - staterunner.go
 faucet
 geth
 internal/browser
 p2psim
 puppeth
 rlpdump     rlpdump is a pretty-printer for RLP data
 swarm       Command bzzhash computes a swarm tree hash.
 utils
 wnode
Geth Arch
REF
       ┌────────┐              ┌───────┐
       │JSON RPC│              │LevelDB│
       └────────┘              └───────┘
            ↑                      ↑
┌─────┐     │       ┌─────┐        │  ┌───────┐
│SWARM│     └──────→│ EVM ┼←───────┘  │Whisper│
└──┬──┘             └─────┘           └───┬───┘
   │                   ↓                  │
   │         ┌─────────────────────┐      │
   └────────→│     P2P/Gossip      │←─────┘
             └─────────┬───────────┘
                       ↓
                  ···· ···   ···
                 ··   ·   ···  ··
                 ·   Network    ·
                 ······     ····
                       ·····


LevelDB (key/value) storage backend.
  - entries stored lexicographically sorted by keys.
    (sorting comes-in very useful for querying)
  - Arbitrary byte arrays:
    keys and values are treated as simple arrays of bytes,
    so content can be anything from ASCII strings to binary blobs.
  - Compressed storage:
    Google’s Snappy compression library (optional) dependency,
    highly optimized for fast compression (vs high compress ratio)
  - Ex ussage:
    var level = require('level')
    var db = level('./db', { valueEncoding: 'json' })

    db.put('key', { example: true }, function (err) {
      if (err) throw err

      db.get('key', function (err, value) {
        if (err) throw err
        console.log(value)
      })
    })

Data structure in Ethereum
Geth Key Handling
- Keys are stored under /keystore(backup regularly)
- keyfiles format(2017-05): UTC--˂created_at UTC ISO8601˃-˂address hex˃

geth account [arguments...]
geth account help 
    subcommand:
    - new   : create new accounts. Will ask for password/passphrase and
              return its public address.
    - list  : list all existing accounts.
              (Example Output)
              → Account #0: {a94f5374fce5edbc8e2a8697c15331677e6ebf0b}
              → Account #1: {c385233b188811c9f355d4caec14df86d6248235}
              → ...
    - import: import a private key into a new account
              $ geth --datadir /someOtherEthDataDir  account import ./key.prv
              → The new account will be encrypted with a passphrase.
              → Please enter a passphrase now.
              → Passphrase:
              → Repeat Passphrase:
              → Address: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d}
              → export (unencrypted format ºNOTº supported)
    - update: migrate to newest key format. account will be saved in newest version
              in encrypted format.  you are prompted for passphrase to unlock
              old-format account wallet and another to save updated file
              (can also be used to change file/wallet password)
              $ geth account update a94f5374fce5edbc8e2a8697c15331677e6ebf0b
              → Unlocking account a94f5374fce5edbc8e2a8697c15331677e6ebf0b | Attempt 1/3
              → Passphrase:
              → 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
              → Account 'a94f5374fce5edbc8e2a8697c15331677e6ebf0b' unlocked.
              → Please give a new password. Do not forget this password.
              → Passphrase:
              → Repeat Passphrase:
              → 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b

    - ??????: change password

using account NON-interactively (not connected to a geth node):

   Ex. unlock account wallet for one session:
   $ geth --unlock ˂hex_formated_comma_separated_account_list˃
   Example:
   $ geth --unlock primary --rpccorsdomain localhost --verbosity 6 2˃˃ geth.log
   $ KEYLIST="0x407d73d8a49eeb85d32cf465507dd71d507100c1"
   $ KEYLIST="${KEYLIST},0,5"
   $ KEYLIST="${KEYLIST},e470b1a7d2c9c5c6f03bbaa8fa20db6d404a0c32"
   $ geth --unlock "${KEYLIST}"
Geth Console
@[https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console]
- JS command line console to control geth.

  $ gethºattachº Oº--preloadº"script1.js,..."                                http://123.123.123.123:8545
  $ gethºattachº                              Bº--execº " eth.blockNumber "
         ^^^^^^    ^^^^^^^^^                    ^^^^^^                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
     ºAttach toº   (opt)preload                 batch                        local node if no specified
     ºrunning  º   CSV script                    mode
      node         list
┌────────────────────────────────────────┬───────────────────────────────────────────────────
│ºEx1: EXAMINE TX:º                      │ºEx2: CHECK ACCOUNT BALANCE/Sº
│ $OºTX_IDº='0xaeb..b49'                 │ cat gethPreload.js ←  ˃ ºloadScriptº("gethPreload.js")
│ $ web3.eth.getTransaction(OºTX_IDº,    │                       ˃OºcheckAllBalances()º;
│     function(e, r) {                   │
│        if (e) {                        │ function OºcheckAllBalances()º {
│          console.log(e);               │   var totalBal = 0;
│          return;                       │   for (var acctNum in eth.accounts) {
│        }                               │     var acct = eth.accounts[acctNum];
│        console.log(JSON.stringify(r);  │     var acctBal = web3.fromWei(
│     } );                               │                     eth.getBalance(acct), "ether");
│                                        │     totalBal += parseFloat(acctBal);
│                                        │     console.log(
│                                        │        acct + " balance: " + acctBal + " ether");
│                                        │   }
│                                        │ };
└────────────────────────────────────────┴───────────────────────────────────────────────────
Config Trouble-shoot
Full 1.0 API
console.dir(eth) does NOT work but all that needed is enter the object name in the prompt

˃ eth                                                                         ˃ web3
→ {                                                                           → {
→   accounts: ["0xed9d02e382b34818e88b88a309c7fe71e65f419d"],                 →   admin: {
→   blockNumber: 5,                                                           →     datadir: "/home/vagrant/singleNodeNetwork/qdata/dd1",
→  ºcoinbase: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",                   →     nodeInfo: {º
→  ºcompile: {                                                                →       enode: "enode://ac6b1096....9373ef@[::]:21000?discport=0",º
→  º  lll: function(),                                                        →       id: "ac6b1096ca56b9f6d00....373ef",º
→  º  serpent: function(),                                                    →       ip: "::",º
→  º  solidity: function()                                                    →       listenAddr: "[::]:21000",º
→  º},                                                                        →       name: "Geth/v1.7.2-stable-94e1e31e/linux-amd64/go1.9.5",º
→  ºdefaultAccount: undefined,                                                →       ports: { discovery: 0, listener: 21000 },º
→  ºdefaultBlock: "latest",                                                   →       protocols: { eth: {...} }º
→  ºgasPrice: 0,                                                              →     },º
→   hashrate: 0,                                                              →     peers: [],
→   mining: false,                                                            →     ...
→   pendingTransactions: [],                                                  →   },
→   protocolVersion: "0x3e",                                                  →   ...
→   syncing: false,                                                           →   debug: { ...  },
→   call: function(),                                                         →   eth: {
→   contract: function(abi),                                                  →     accounts: ["0xed9d02e382b34818e88b88a309c7fe71e65f419d"],
→   estimateGas: function(),                                                  →     blockNumber: 5,
→   filter: function(options, callback, filterCreationErrorCallback),         →     coinbase: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
→   getAccounts: function(callback),                                          →     ...
→   getBalance: function(),                                                   →     gasPrice: 0,
→   getBlock: function(),                                                     →     hashrate: 0,
→   getBlockNumber: function(callback),                                       →     pendingTransactions: [],
→   getBlockTransactionCount: function(),                                     →     syncing: false,
→   getBlockUncleCount: function(),                                           →     call: function(),
→   getCode: function(),                                                      →     getAccounts: function(callback),
→   getCoinbase: function(callback),                                          →     getBalance: function(),
→   getCompilers: function(),                                                 →     getBlock: function(),
→   getGasPrice: function(callback),                                          →     getBlockNumber: function(callback),
→   getHashrate: function(callback),                                          →     getBlockTransactionCount: function(),
→   getMining: function(callback),                                            →     ...
→   getPendingTransactions: function(callback),                               →     getStorageAt: function(),
→   getProtocolVersion: function(callback),                                   →     getTransaction: function(),
→   getRawTransaction: function(),                                            →     getTransactionCount: function(),
→   getRawTransactionFromBlock: function(),                                   →     getTransactionFromBlock: function(),
→   getStorageAt: function(),                                                 →     getTransactionReceipt: function(),
→   getSyncing: function(callback),                                           →     ...
→   getTransaction: function(),                                               →   },
→   getTransactionCount: function(),                                          →   isIBAN: undefined,
→   getTransactionFromBlock: function(),                                      →   miner: {  ...  },
→   getTransactionReceipt: function(),                                        →   net: { ...  },
→   getUncle: function(),                                                     →   personal: {
→   getWork: function(),                                                      →     listAccounts: ["0xed9d02e382b34818e88b88a309c7fe71e65f419d"],
→   iban: function(iban),                                                     →     listWallets: [{
→   icapNamereg: function(),                                                  →         accounts: [...],
→   isSyncing: function(callback),                                            →         status: "Unlocked",
→   namereg: function(),                                                      →         url: "keystore:///.../keystore/key1"
→   resend: function(),                                                       →     }],
→   sendIBANTransaction: function(),                                          →     ...
→   sendRawTransaction: function(),                                           →   },
→   sendTransaction: function(),                                              →   ..
→   sign: function(),                                                         →   shh: { ...  },
→   signTransaction: function(),                                              →   txpool: { ... },
→   submitTransaction: function(),                                            → }
→   submitWork: function()
→ }
Disk Space
REF:
@[https://ethereum.stackexchange.com/questions/143/what-are-the-ethereum-disk-space-needs/826#826]
Last Update: May 14th, 2018 / Block ~ 5_600_000
Geth (Go) 1.8.3 Ubuntu 16.4 LTS,  VPS + SSD | Parity (Rust)
--------------------------------------------+--------------------------------------------
Client / Mode    | Block Number |Disk Space | Client / Mode      |Block Number|Disk Space
=================|==============|========== | ===================|============|==========
geth light       | 5_600_000    |363M       | parity light       |5_600_000   | 89M
geth fast full   | 5_600_000    |142G       | parity warp fast   |5_600_000   | 82G
geth full full   | ?_???_??? [1]|239G + [1] | parity full fast   |5_600_000   | 78G
geth full archive| 4_980_000 [2]|671G       | parity full archive|5_600_000   |1.1T
                                            |
[1] disk was full, I wasn't able to repeat  |
    this sync mode                          |
[2] I didn't manage to fully sync           |
    within 6 weeks, unfortunately.          |
--------------------------------------------+--------------------------------------------
Update 2019-08-08:
zation of a quadratic CPU and disk IO complexity,
REF: @[https://blog.ethereum.org/2019/07/10/geth-v1-9-0/]
"""We've run a fast sync benchmark on two i3.2xlarge AWS EC2 instances
   (8 core, 61 GiB RAM, 1.9 TiB NVMe SSD) with --cache=4096 --maxpeers=50
   (defaults on v1.9.0) on the 25th of April."""

ºFAST SYNCº
     Version          Sync time   Disk size   Disk reads  Disk writes
     Geth v1.8.27       11h 20m      176GiB      1.58TiB      1.94TiB
     Geth v1.9.0          4h 8m      131GiB      0.91TiB      1.06TiB
---------------------------------------------------------------------
ºFULL SYNCº
     Version          Sync time   Disk size   Disk reads  Disk writes
     Geth v1.8.27    6d 15h 30m      341GiB      28.9TiB      21.8TiB
     Geth v1.9.0     6d  8h  7mº     303GiB      40.2TiBº     32.6TiB*

"""...ºreducing the memory use by about 1/3rdº and
      ºcompletely removing spurious memory peaks (Shanghai DoS)º.
    The reason for the higher disk IO is due to using less memory
    for caching, having to push more aggressively to disk."""

ºARCHIVE SYNCº
- archive sync benchmark
  - two m5.2xlarge AWS EC2 instances (8 core, 32 GiB RAM, 3TiB EBS SSD)
    with --cache=4096 --syncmode=full --gcmode=archive.

    Version       Sync time   Disk size   Disk reads  Disk writes
    Geth v1.8.27     62d 4h     2.57TiB     69.29TiB     49.03TiB
    Geth v1.9.0     13d 19h*    2.32TiB    104.73TiB     91.40TiB

rºEBS volumes are significantly slower than physical SSDsº
rºattached to the VM. Better performance can be achieved º
rºon VMs with real SSDs or actual physical hardware.     º
Quorum-Maker
@[https://github.com/synechron-finlabs/quorum-maker]
C&P from https://github.com/synechron-finlabs/quorum-maker:
Synechron's Quorum Maker is a tool that allows users to create and manage Quorum network.
Manually editing configuration files and creating nodes is a slow and error-prone process.
Quorum Maker can create any number of nodes of various configurations dynamically with
reduced user input. This provides a wizard-like interface with a series of questions to
guide the user when creating nodes. Quorum Maker can create nodes to:

  - run with docker-compose (Raft consensus/Quorum 2.2.0) for easy use in development environments;
    or
  - nodes to be distributed on separate Linux boxes or cloud instances for a production environment
    (Raft consensus/Quorum 2.2.0)

ºINSTALL PRE-REQUISITESº
- install docker-CE ("Long Term Support") as explained in https://docs.docker.com/install/

ºINSTALL QUORUM-MAKERº
root@.../# git clone https://github.com/synechron-finlabs/quorum-maker

ºQUORUM-MAKER USSAGEº
root@/.../quorum-maker# ./setup.sh º--helpº
    ....
    Version 2.6.2 Built on Quorum 2.2.1
    Utility to setup Quorum Network

    join      Create a node and Join to existing Network
    attach    Attach to an existing Quorum Node. The node created hosts only Node Manager
    dev       Create a development/test network with multiple nodes

    Options:

    For create command:
      -n, --name              Name of the node to be created
      --ip                    IP address of this node (IP of the host machine)
      -r, --rpc               RPC port of this node
      -w, --whisper           Discovery port of this node
      -c, --constellation     Constellation port of this node
      --raft                  Raft port of this node
      --nm                    Node Manager port of this node
      --ws                    Web Socket port of this node
      -t, --tessera           Create node with Tessera Support (Optional)

    E.g.
    ./setup.sh create -n master --ip 10.0.2.15 -r 22000 -w 22001 -c 22002 --raft 22003 --nm 22004 --ws 22005

    For join command:

      -n, --name              Name of the node to be created
      --oip                   IP address of the other node (IP of the existing node)
      --onm                   Node Manager port of the other node
      --tip                   IP address of this node (IP of the host machine)
      -r, --rpc               RPC port of this node
      -w, --whisper           Discovery port of this node
      -c, --constellation     Constellation port of this node
      --raft                  Raft port of this node
      --nm                    Node Manager port of this node
      --ws                    Web Socket port of this node
      -t, --tessera           Create node with Tessera Support (Optional)

    E.g.
    ./setup.sh join -n slave1 --oip 10.0.2.15 --onm 22004 --tip 10.0.2.15 -r 23000 -w 23001 -c 23002 --raft 23003 --nm 23004 --ws 23005

For attach command:
  -n, --name              Name of the node to be created
  --ip                    IP address of existing Quorum
  --pk                    Public Key of existing Constellation
  -r, --rpc               RPC port of the existing Quorum
  -w, --whisper           Discovery port of this node
  -c, --constellation     Constellation port existing node
  --raft                  Raft port of existing node
  --nm                    Node Manager port of this node (New Node Manager will be created by this command)
  --active                Active attachment mode
  --passive               Passive attachment mode

E.g.
./setup.sh attach -n slave1 --ip 10.0.2.15 --pk BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo= -r 22000 --whisper 21000 --constellation 9001 --raft 50401 --nm 11004 --active

For dev command:
  -p, --project           Project Name
  -n, --nodecount         Number of nodes to be created
  -e, --expose            Expose docker container ports (Optional)
  -t, --tessera           Create node with Tessera Support (Optional)

E.g.
./setup.sh dev -p TestNetwork -n 3

-h, --help              Display this help and exit

Running on kubernetes
@[https://github.com/majd1239/Quarum-Maker-Kubernetes]
See also: https://github.com/synechron-finlabs/quorum-maker/issues/75
Monitoring & Metrics
@[https://github.com/ethereum/go-ethereum/wiki/Metrics-and-Monitoring]

˃ºdebug.metrics().p2p.InboundTrafficº        ˃ºdebug.metrics().chain.insertsº
{                                            {
  Avg01Min: '169.12K (2.82K/s)',               Avg01Min: '10 (0.17/s)',
  Avg05Min: '1.92M (6.42K/s)',                 Avg05Min: '61 (0.20/s)',
  Avg15Min: '3.57M (3.96K/s)',                 Avg15Min: '168 (0.19/s)',
  Total: '5.83M (2.97K/s)'                     Maximum: '2.157261657s',
}                                              Minimum: '2.271716ms',
                                               Percentiles: {
˃ºdebug.metrics(true).p2p.InboundTrafficº        20: '6.993756ms',
{                                                50: '12.342836ms',
  AvgRate01Min: 1599.6190029292586,              80: '21.765944ms',
  AvgRate05Min: 5367.754506658111,               95: '218.500479ms',
  AvgRate15Min: 3761.057607521597,               99: '376.015984ms'
  MeanRate: 2907.3919382272857,                },
  Total: 5901154                               Total: '432 (0.22/s)'
}                                           }



$ºgeth monitorº   ← periodically queries a node for
                    metrics and plots them on the terminal

$ geth monitor [--attach=api-url] metric1 metric2 ... metricN
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
             Ex metrics:
                   system/memory/allocs/AvgRate05Min        ← Full canonical metric
                   system/memory/allocs                     ← Group of metrics
                   system/memory                            ← Group of metrics
                   system/memory/allocs,frees/AvgRate01Min  ← Multiple branching metrics
                   system/memory/*/AvgRate01Min             ← wildard pattern   (Not supported by planned)
                   system/memory/allocs/!AvgRate01Min       ← Exclusion pattern (Not supported by planned)

Available metrics (use geth monitor for full list)
    system/memory/
        allocs: number of memory allocations made
        frees: number of memory releases made
        inuse: memory currently being used
        pauses: time spent in the garbage collector
Geth 1.9 Release Notes
@[https://blog.ethereum.org/2019/07/10/geth-v1-9-0/]
Release page      : @[https://github.com/ethereum/go-ethereum/releases/tag/v1.9.0]
Pre-built binaries: @[https://geth.ethereum.org/downloads/]
Docker images     : @[https://cloud.docker.com/u/ethereum/repository/docker/ethereum/client-go]
Ubuntu packages   : @[https://launchpad.net/~ethereum/+archive/ubuntu/ethereum]
OSX packages      : @[https://github.com/ethereum/homebrew-ethereum]


- Performance Improvements in block processing:
  - The discovery and optimization of a quadratic CPU and disk IO complexity,
     originating from the Go implementation of LevelDB.
  - optimization of various EVM opcodes
  - ...

- Allow separated database into two parts:
  - Recent blocks, all state and accelerations structures   ← Ideal to ºput on SSDº since both disk IO performance is crucial.
    are stored in fast key-value store (LevelDB)
  - Blocks and receipts that are older than a cutoff        ← infrequent access,ºHDD should be more than suitableº
    threshold (3 epochs) are moved out of LevelDB into a      Use --datadir.ancient to move outside chaindata ("SSD" disk)
    custom freezer database, that is backed by a handful
    of append-only flat files.

  - Ex: A fresh fast sync at block 7.77M placed
    - 60GB of data into LevelDB
    - 79GB of data into the freezer

  -  NOTE: What happens if one of the two databases goes missing?
     - If the freezer database is deleted the node would become unusable.
     - If the state   database is deleted, Geth will reconstruct all its
       indices based on the frozen data and then do a fast sync on top
       to back-fill the missing state. Next command will actually delete
       it and reconstruct from freezer:
       $ geth removedb --datadir ... --datadir.ancient ...
       (will take 1+ hours in mainnet)

- GraphQL (--graphql CLI flag):
- Ported from work by [Raúl Kripalani, Kris Shinn, Nick Johnson, Infura, Pegasys]
  pioneering both the GraphQL spec and its implementation
- Support for flexible queries (INNER JOINS) in a single round trip, saving lot of bandwidth.
- Ex: find all the ENS domain registrations on the Görli testnet!
  STEP 1: Start Geth v1.9.0 on Görli with GraphQL enabled
  $ geth --goerli --graphql  ← should sync in 1-2 minutes tops

  STEP 2: point browser to the built in GraphQL explorer:
  $ http://localhost:8547
   ºintegrated code completionº
   ºfield documentation       º
   ºlive query execution      º

  STEP 3: sample query to find the ENS HashRegistered events and
          returns the address of the user doing the registration
          along with the block number and timestamp it was included in:

GraphQL:
{
  logs(                                ← "SELECT FROM  logs INNER JOIN address ON ... "
    filter: {                          ←   "WHERE"
      fromBlock: 0,                    ←     "BLOCK ˃ 0 AND"
      addresses: ["0xf105....62"],     ←     "ADDRESSES IN (${ENS_CONTRACT}) AND "
      topics   : [["0x0f0...670"]]     ←     "TOPICS    IN (HashRegistered) "
    }                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  )
  {
    transaction {                      ← RETURN:
      hash
      from {
        address                        ← + address of the user doing the registration
      }
      block{
        number                         ← + block number
        timestamp                      ← + timestamp
      }
    }
  }
}

ºSUPPORTED HARDWARE WALLETSº
 - LEDGER WALLETS
   - Ledger Nano S
   - Ledger Nano X (via USB)
   - v1.9.0 will now use  canonical HD derivation path
     used by all Ethereum wallets (and presently by Ledger too).
   Ledger SETUP:
   - (Linux only) explicitly allow user to access wallet via udev rule
   - Plug Ledger Nano S/X
   - Unlock via your PIN code.
   - Start the Ethereum app on your Ledger
     (Geth will log Ethereum app offline).
     - You can list all your accounts like:
       - Alternative 1: Geth console like:
         ~ personal.listWallets
           ^^^^^^^^^^^^^^^^^^^^
           This will auto-derive any accounts that
           you've used before + 1 empty new one.
       - Alternative 2: RPC 'personal_listWallets'

 - TREZOR WALLETS
   - Trezor One: Geth v1.9.0 implements the new WebUSB protocol
                 supporting updated Trezor One models, and old
                 USB HID protocol for non-updated devices.
     Trezor One SETUP:
     - (Linux only) explicitly allow user to access wallet via udev rule
     - Plug Trezor One
     - Geth will detect it but will prompt you to open it.
     - Call personal.openWallet('trezor://...')
       with the URL of the device.
                ^^^^^^^^^^^^^^^^^^
                check it via personal.listWallets
     - console will keep prompting for PIN entry and password as needed.
     - Calling via RPC, openWallet returns a detailed error if it needs another call.
     - list accounts in a similar way to Ledger wallets.
     Geth will forward the signing request to the Trezor.
   - Trezor Model T:
     Trezor Model T SETUP: (workflow is simpler as PIN entry is done on device)
     - (Linux only) explicitly allow user to access wallet via udev rule
     - Plug Trezor Model T
     - unlock via PIN code (Geth should detect it)
     - list accounts in a similar way to Ledger wallets.

 - STATUS KEYCARDS
   - full HD hardware wallet ºbased on Java SmartCardsº
   - Status keycard can be used via Geth only through
     the PC/SC daemon for now (you need to install it)
     and via USB (the +iD is a good USB smartcard reader).

   PRE-SETUP:
     - initialize Status keycard
   SETUP:
     - Plug in your Status keycard via a USB card reader.
     - Check the status of your card via personal_listWallets.
     - Permit Geth to use the card via personal.openWallet('keycard://...').
       - The very first time Geth will ask you to pair your card via the passphrase.
       - In normal operation, Geth will ask you to unlock your card via your PIN code.
       - On too many wrong PINs, Geth will ask you to reset your card via your PUK code.
       - On too many wrong PUKs, your card will be bricked and you’ll need to reinstall it.
       - Alternatively you can do the same thing through RPC via multiple personal_openWallet().

ºCLEF (wallets everywhere!)º
- accounts and networking don't go well together security wise,
- Geth v1.9.0 ships a standalone signer for the entire Ethereum ecosystem
  called Clef.
- major features:
  - remove account management from Geth allowing Geth to
    be an "insecure" network gateway into Ethereum, fixing
    the issues when accidentally exposing accounts via RPC
    (old method is still available for compatibility)
  - Usable by arbitrary programs (Geth, Parity, Trinity, Metamask, MyCrypto, decentralized apps,...)
    - Clef exposes a deliberately tiny external API via IPC (default) or HTTP,
      to allow signing  requests to Clef. Clef in turn will prompt
      the user for manual confirmation.
  - Pluggable interface
    - designed to work with any interface: cli, web, Android, ..
    - Clef exposes an extended internal API solely via standard input/output.
      and JSON-RPC IO streams.
    - pre-built CLI interface
  - Embedded 4byte database!
    The 4byte database enable by looking at the first 4 bytes of the
    giant TX blob, to guess what the rest of the data is meant to represent,
    and can thus show the user a meaningful dump of what they are about
    to confirm (images above and below courtesy of Etherscan) like:
    0xd459fc46.... mapped to:
    #      Name             Type      Data
    0     _recentNumber     uint256   4638288
    1     _recentHash       bytes32   dbb5e8.....
    2     _hash             bytes32   488c....
    3     _sectionIndex     uint64    140
    4     v                 unit8[]   28
                                      28
    5     r                 bytes32[] b85...
                                      dc7...
    6     s                 bytes32[] 38fb6..
                                      5d858...
   ºClef send the decoded call back to the UI, and add warningº
   ºmessages if the data does not match the method signature! º

  - Programmatic rules for automated (batch) transactions.
    (e.g. Clique signer, Raiden relay, Swarm exchange, etc).
    Clef solves this via an encrypted key-value store and an ingenious
    rule engine! Instead of prompting the user to confirm each and every
    request via a passphrase entry, we can permit Clef to sign on our
    behalf by storing our passphrase in its encrypted database.
    This will only allow passwordless signing, but still needs
    manual confirmation!
    - As a second step, however, we can also provide Clef with a
      JavaScript rule file, that will run whenever a request arrives
      and can decide to auto-confirm, auto-reject, or forward the request
      for manual confirmation.
    - The JavaScript rules have access to the entire request and can
      also store arbitrary data in a key-value store for persistence.
      Ex:
      function ApproveSignData(req) {
        if (req.address.toLowerCase() == "0xd9....") {
            if (req.messages[0].value.indexOf("bazonk") ˃= 0) {
                return "Approve"
            }
            return "Reject"
        }
        // ... Otherwise continue with manual processing
        ...
      }

ºLIGHT CLIENTSº
- Geth v1.9.0 ships a new ultra light client.
  This mode aims to position itself midway on the security spectrum
  between a trusted server and a light server, replacing PoW verification
  with digital signatures from a majority of trusted servers.
- With enough signatures from independent entities, you could achieve
  more than enough security for non-critical DApps. That said,
 ºultra light client mode is not really meant for your average node,       º
 ºrather for projects wishing to ship Geth embedded into their own process.º

ºCHECKPOINT ORACLEº
 - Light clients, instead of downloading and verifying each header from
   the genesis to chain head, use a hard coded checkpoint (shipped within Geth)
   as a starting point. Of course, this checkpoint contains all the necessary
   infos to cryptographically verify even past headers, so security wise
   nothing is lost.
   Some shortcomings:
   - hard coded into release binaries: older releases will always start
     syncing from an older block.
   - Can NOT be used in private networks.
 - Geth v1.9.0 ships support for an on-chain checkpoint oracle. Instead of
   relying on hard-coded checkpoints, light clients can reach out to untrusted
   remote light servers (peer-to-peer, no centralized bs) and ask them to
   return an updated checkpoint stored within an on-chain smart contract,
   and cryptographically prove that the returned data was signed by a required
   number of approved signers!
   - How does a light client know who's authorized to sign an on-chain checkpoint?
     - For networks supported out of the box, Geth ships with hard coded checkpoint
       oracle addresses and lists of authorized signers (so you're trusting the same
       devs who ship Geth itself).
     - For private networks, the oracle details can be specified via a config file.
   - checkpoint oracle contract is an especially nasty beast:
     a) it goes out of its way to retain security even in the face of chain reorgs
     b) it needs to support sharing and proving checkpoints to not-yet-synced clients.
     Geth v1.9.0 ships a "checkpoint-admin" tool specifically for this contract.
     (useful to run your checkpoint oracle in a  private network).
     $ checkpoint-admin \                      ← query status of deployed contract
         --rpc ~/.ethereum/rinkeby/geth.ipc \
         status
     Oracle =˃ 0xebe8eFA441B9302A0d7eaECc277c09d20D684540

     Admin 1 =˃ 0xD9C9Cd5f6779558b6e0eD4e6Acf6b1947E7fA1F3
     Admin 2 =˃ 0x78d1aD571A1A09D60D9BBf25894b44e4C8859595
     ...
     (can also be used to deploy or sign updated checkpoint)

ºMONITORINGº
- Metrics collection gathering     exposed metrics:
  $ geth ... --metrics --pprof   ← http://127.0.0.1:6060/debug/metrics
  (pull based monitoring)          (ºexpvarº -Go ecosystem friendly format)
                                   http://127.0.0.1:6060/debug/metrics/prometheus
                                   (prometheus friendly format)

  $ geth ...              + "set of --metrics.influxdb subflags"
  (push based monitoring)   (server, ddbb, user/password, ...)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                            see the METRICS AND STATS OPTIONS section
                            of geth help for details

ºMETRICS VISUALIZATIONº
You can import next grafana dashboard:
(
cat ˂˂ EOF
H4sIAIdjTF0AA+1dW3PbNhZ+z6/gsN2dNuO4omzZ1s5kdhInadomrbd2+9JkNBAJSagpkiFBX+rx
f18AvAAkQOpCkZIV5EGxAArngnP5DgiCD88MwxyNkBfEODL/Y/xFvhvGA/skPR6YQ9JqvrkcXfz+
28e3V+/f/nFpHmTdLhhDl/YHoT+HeAbjiHc6MLJDFGDke/QS3oHvAzaoAzCI/Di0Ie8L3HiKvJ+c
qkGT/l9Tti74FeyCR/L5+SARKYRfYhRChVAZ/WkIJsADfHDkKJszJfxY7riBYZRKd3LYP+ynTByo
yQXAI8qSiQUzJSmxWSBUT0OlUlSpTE9Wo4qkddg77K0hW4S8qQsjDLBM8lLRJ0uZTyfwPJ9cS3rp
fCbkTRdFOJ9dzhTpGcfIxT/RkawD3iooh5B48cJIJ9R48cIULoMeGLv0EhzGUGifIUfRimzfO/dd
P6RjhtMx+K53YPQti3wMBgeG9b04dCb9Ky6O8W/jlQtDHInX8emMZmMfhI6Z9j2y/z8/S2fChA7C
JW7NqQcxcyAvdt2khVrTle+7GAWkvccaUeEShGEIUle1Bic966R/2rMGx8m1LvKumSMls8FmW+FY
tu+6IIggHXkC3CjXE+EAORc+n7tEoaX5uSXf+8dCw13GbPr9nn7PNFE0trM+DxE5d595yEHYTezu
PsJwLsei0L9VWzhwEYjYBDPuOdkxYC1FOemEfYDeFDPZeoV2qLpctMhvHwph9pFzOUGuKyqrWp8n
JX2eLVCnpVan1csHMl04hZ5TJEW0MvVeRVep7RWkot03U0WrHYch9LCiZw7uVK3IU7SGaDrDl4kv
lvuimX8ruygmvuYqrr4BbswnRVIEMXrWK47GGm+Rgwu2W/IP1kQ968JHHv7oM1ZZA59RP8iDGacY
QGIJHgZTSTYzoEOFwEEx/c2g2C4bFtGzA0PIgtLE9YUgG8EQweg3EmuJCcES01EAbKiyXxKo7WuJ
CnGlIIDOB6ITqQ+DcAoFSEH/cQOioesuYOxFzCNHdhCPyJ+uDxwhElLb98M5oEZDnHgORwn/xUuI
CmBIZvMdsDELxFahOzHgd/k4UTEGpAqbJKDjlZk3Px6swvktQLhtzpEvU8k5f70W5wQX2F0onRjD
rILxc4Hx9C8hcs8Ihpv5riNF9Dl8R3CLkMTy9t/hNHWu0g8uZ2iC5V+kueH84g8hMeTpUgh70QyE
LLuVIkzkh7gUXFlwGWXpBXkOukFOTOKQFGcEOCpivjtwh0oBfhzb14lPiQLQSJnGGCqjAm+UrlZH
yTwa/vVZYvEe3MEaV+bWkkaw4kRnVUKRDdrhT1+DCEq2k6QD6fIkH0jNgjgLHYBzSn4V7gCfkr3f
y9POkq0qy9L2D/AmZ7oAEvccyIjfa4DMmcYxGsd0gmNI+QS/SxPrHM798H4EXNe3o7+s+efv206v
jNTGIE3Kf0xLuZYZl2k0ADQp3zPots63TGPn8MxHpg0NaZpBmvE9LpuKBjTVfGpAsyagscQL6hAN
T5oa0WhE0xGicVB0PQohcFg47ATSUGrNEY0kxG2IMOxOCkZuCYCzTaDwhuhFw4RmMOF1oEHCDoKE
Lm5JnaoT9amQC+puSf0K8a0fig645/ekrP4ChZ6pFTpcaS2n5OQJ8Ck1ctxT6khsvNzILLzUKIKe
cmxcD/MIrqIhzzYgT9APRsibkvTbDURIaTVfBcm5h90xD+t435WVkKsQTCbI1hhHY5w9xDj7BgcK
DTV44PRU4wGNB1rFAzSZBhCGUdtpVEFk7dUOyrSDiMCdAABGaYPYhbB009HaTEJqx7HLRcEyNHJZ
C7l4vge3Dwk0dNnG8ox1rIYP+e/ql2deu759bc8A0Z/kGpUrNDawZ/CKWL0fS55tU6T2mqSsaejH
niw56/+TWr26q2jw5jf94dA+PhHdi21D7x+dHhAoNTwwjnsHRu/wbFjYiv6Nc3wMjoApzXWF05hT
ELPUL0wHMbWMT6snqp0YW9YhNqfGVjaZPJh+oLYu4QXxio8gvIZhJSqqNJp+yWiOFtnMQG0zVu+M
N6TJpjy/Crw1B0FAqvyrxGwsVXtNGMueGmCR0MC+geFdKUrcZNOwMNhkg4XAmy4YrF8TEcjUvyGV
wUWG8IT5l9Gl7XsetLGw0YNdc0Upl5Snhp5+hCeIzpPwFFHa+M73CNz+h9EZ9P4l9JNMLv2GtVX+
hOnkI4lHNSklSe5FwMx6cCKN+esPr0odfv6DGoUSdBteuwlYFYyXllXFx0uOLOLW1hn5OBtSv7bO
Cn49iV1VNUFHFsdJhumTyGANjwoDiE4qYwJaTJFx4nn5ma5lETWLpKMZBA77IFXAhkGeEjbXAzhR
jhoAV4/TPhAAG2GjJFSeKlQPQzFHE63xTLRG1ltvjT7FgebLJQ0x8+uFtsguzJ6xy2piZZ5bbemh
LiuuuCyx/nLDsBT6xVRQG/oFppTLDS3urPhadk/0i+1Peumg9UAn70iUqayzhiAwHkIboqD1x1qU
ZNZZRBBYH1PY3jbjCiI7t35wTnXC0pJeRGi2iLAj1XmFD+wcn5LRt7eKoKvtJ1VtSzd4qjHXEW/Q
5bYut3mPLreXQqH4LiC5fhQQ2EIsf19q7bd30I6ZckhkAl5EuGNmLMEOXXXvaNVtDYSG+hSwYNef
Lrsr4/jXWHa3G/Ck3W95IGped6ecf4lh3P5jl1NAVd284k6ZJnUwcNvmWUFk56rtK56ODKoZXXPr
mlvX3Lrm3nrNLd3hrnhqxbI4DtElty65hR5dcq9646el+ydbvsVdlmrPq22d6Z5WppNXlytTHd8C
qFOdTnVCj051qyy2tLNksa0s9yNbGvkqF5Z1qntaqU4q6oYVma435A060+lMx3t0plu1qGtlZ9mW
S7qiTDrL6SyXT8z2s5xc0FWlOX5XWac5neZ0mls5zbV5O3drKY4K81WWc09gn5C4L2ipp3n7VW+s
4VlCnwaSN37Fe4sKutjgEz3Jlh+ikYcvMfAwcuHLT+a32d+fzMdNx031niO6weS7Ly9zwqXDMtZ/
8IcwghywUQFnyjOBiyDNbKQTzvRSSln5kSJ2imt3+lhSatufzxFeSuLzVSUGtk0KIMzO/I22Zeop
EwZlYikx36wrZhw4tBLetqAJG0uJ+nZdUWcsZ29bUsbFUoK+W1fQxD22LukKXvrjqqJGhBGSg7fr
pSkTy3vp+3XF3LKXZoKu4KU/rSvqdr00k3R5L/15XUG37KWZpCt46S87steYnUxk0Bf4wSgSN7vr
vcbrHRKmTzddmk/J7nfkdNOnsYhxVPEWY8vSR5rqRQxhEaOtI87TdV5WNndy1CajtEQ+XQAdROaR
1x37Ka3mayyiADG1mSBENlxTiPbXVQQWmy+liLKnz+fRV/LYIGxL/pWf4jNSfpqvoqiEDWHgEofv
5lx+LlNKtvmSiVIm0uYiAp07lyoj3Hx9RCWX50+I8Xf0DgUuVUq2+VKIKFOyP3M3fC158HSBn62w
DqKQs5GbbVjOet9bYSFEJWcz19u0pAv8cYWVEIWsjdxxw5LW++jPO7I6UHgSOfQDMGX3R/QigT5J
fB+XCbo4Sfyoat8Zr9prjxKne7LGVNOSZ+zrq97KL7kta/S4YiHkaMFLbvWhL4Z+TUsJMEA8Gznj
Ebu7QC2bv7O2ExDv0kjljI2a19auWiurJWJ7EToVqe4dtquufUgyAc9GMN1o0IlUKcG6iVq1zq8U
qru5yqSqm6s3OwJNaR5k9YIGo/qFfHuIRfcMtInf60Ab3feuUZtGbcuitmrA9rSwWg1Me2IIrRac
PS1cVg/JNBrjaOyS7h7yPYMFS/2mwYaQzIH2+B6XzUfjsmo+NS5bE5dZ4gX1wIwf/7DEtiJJyS3i
NnFvkcZ0+4rpIvoEZTdQqAU4lyGHLqRIaS0B5bYKGdJN0wWNaMCgAUMnfHYHGLq4qXh8ok7aR0ve
VLwiMce4xAArHmvf19uKhRNBlEqtOvKxr1/iqOHMqpulCVOjOZyzZwtGtguB1+Bu1aY2I80qd1qt
vEtVIV+DG1ebEnCOoqo9Vq93BAedU10ZTG8aBulbWXuIgPYNKEhniVUhhYF+7ZQGCo2AwtRmKwZb
3rJstwISJm4czXZAPJ9YALGM2009nFREQuyR8AZSrnWcy44v/bxBIb7XkEdDnv2BPM/SYamzUT+i
Ulu9ZG7MiBj6HPwJQ3qPlAp2ljTj+8QfHBAmB+eSXDHl3mRiOA9cgOmxDBmPJMFGWDCMAududiar
WXy8VbRQDi8ehHlbFkbRK+EEeQgnkpgPf/vjl59MkuBmxYM2svAsYiXk2W7swFcMiZW8IbMH8+ru
grB+To+9oQfBik4XkwAh/zI77xTfjZjQtuKnHGTwQEWav8QwvK8Xg89nv9A6hezk0R8On6dPGR0+
//7h8Pl/P5mHz38QB4iuUfBH6F7ee7YKp8mBjNgAm8fofxl3ZrFXEoO2qS9OI10ip9ARR/AqGUiJ
+NRWVYpqgiUVPA+6yUmw5Yky+MGVVM/FcJCfXMm6VKFloUFJB6IqI0xuReXLMzMillBhOQK/osT1
MtdJXS03D1ZCuBINtjTWAivL7MCOI0wy+SanW2GPgsi9w+GgYqJZV91E91qe6OyIniazLYHPguyD
ytmmfeJkH2yA2mkdudN16NXYsjSx1VO7IfGGwzp6wxbo1RNsheICksMVIgQxMXp49Cn7HCafw+Qz
+2/YOIKw/yl8fUwAC5rz0635Sdr+7YvBPKWVHZad3FXiPwsQgdoh/3Gad0dZ/SP6pDkQ7lNlKIt9
ORK/WHP+90D42xK/HPXEHqEc6At/W04i8edMBlqtybGimoo48Ik4sEilfyx+EY5SP3VEfjNeCur7
x2crD2YKI/P3EJE0YVyQeSD/wziFozFKDgK4CP5+f/IepdDzJoen/ZNnj8/+D27JWX7VxQAA
EOF
) | base64 -d | gzip -d

ºDISCOVERY PROTOCOLº
- ºEthereum Node Records (ENR) extensionº Support
  new discovery protocol, which can actually run on top of the old protocol too!
  An ENR is a tiny, 300 byte, arbitrary key-value data set, that nodes can advertise
  and query via discovery. Fixes scenarios in private networks (few nodes),
  network forks, updates, ...
  Nodes can now advertise a lot of metadata about themselves without an expensive
  TCP + crypto handshake, thus allowing potential peers to filter out unwanted
  connections without ever making them in the first place!

ºBOOTNODESº
-BºTo go along our Geth v1.9.0 release, we've decided to launch a new set of bootnodesº
 Bºthat is managed via Terraform and Ansible; and monitored via Datadog and Papertrailº.
   (legacy bootnodes will be gradually sunset)
   New list of bootnodes is:
 enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303 (Singapore, AWS)
 enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303 (Virginia, AWS)
 enode://ca6de62fce278f96aea6ec5a2daadb877e51651247cb96ee310a318def462913b653963c155a0ef6c7d50048bba6e6cea881130857413d9f50a621546b590758@34.255.23.113:30303 (Ireland, AWS)
 enode://279944d8dcd428dffaa7436f25ca0ca43ae19e7bcf94a8fb7d1641651f92d121e972ac2e8f381414b80cc8e5555811c2ec6e1a99bb009b3f53c4c69923e11bd8@35.158.244.151:30303 (Frankfurt, AWS)
 enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303 Australia, Azure)
 enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303 (Brazil, Azure)
 enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303 (South Korea, Azure)
 enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303 (West US, Azure)

ºOTHER CHANGESº

    Source code, git tags and whatnot on our GitHub release page.
    Pre-built binaries for all platforms on our downloads page.
    Docker images published under ethereum/client-go.
    Ubuntu packages in our Launchpad PPA repository.
    OSX packages in our Homebrew Tap repository.

And as a last word before signing off (better twice than none):

Warning: We’ve tried our best to squash all the bugs, but as with all major 
  releases, we advise everyone to take extra care when upgrading. The v1.9.0 
  release contains database schema changes, meaning it’s not possible to 
  downgrade once updated. We also recommend a fresh fast sync as it can 
  drastically reduce the database size.

Parity
External Links
@[https://parity.io/parity.html]
@[https://github.com/paritytech/parity]
@[https://github.com/paritytech/parity/wiki/Coding-guide]
@[https://github.com/paritytech/parity/wiki]

features
"full" Ethereum Wallet and Dapp environment with web-front-end ("http://127.0.0.1:8180"):
- Account, address-book and multi-sig management
- Key creation, importing and exporting
- Web3 Ðapp browser
- Hardware and electronic cold-wallet support
- Name registry support
- Contract development, deployment and interaction environment

Setup guide
NOTE: Parity is already supported by Puppeth that probably
     is the best way to deploy
@[https://github.com/paritytech/parity/wiki/Setup]

- One-line binary installer
-  building from source,...
Accounts
Wallets and
Vaults
Existing parity-wallet options to store tokens and Ether
REF
- ACCOUNTS: most basic way to store assets. [public key/private key]. 
  Ussage: used to sign transactions, enable authentication, and prove ownership.

- PARITY WALLET: smart contract managing assets.
@[https://github.com/paritytech/parity/blob/master/js/src/contracts/snippets/enhanced-wallet.sol]
 - Can me owned by multiple accounts.
 - Unlike accounts, contract wallets behaviour can be customized.
 - Common use-case: multi-signature wallets, that allow for transaction logging, withdrawal limits, and rule-sets for signatures required.
 - support in Parity web UI:
   Go to: Account_tab → +WALLET → Multi-Sig Wallet
   - select 2+ owners and number of signatures to withdraw funds, daily withdrawal limit, ...
   - 'publish' the new contract singing the transaction with one of wallet-owners accounts
- VAULTS: Offers additional privacy feature to lock away your accounts behind a second layer of protection encrypting the meta-data (e.g., the public address) and therefore hiding the accounts until you unlock the vault.
  - support in Parity web UI:
    Go to: Account_tab → +VAULT → +CREATE VAULT
    - Follow instruction on the screen
    - Go go: Account_tab and select accounts to move
        to vault.
        Once moved into the vault, the addresses are
        encrypted and not stored as plain text on disk
        anymore. Closing the vault hides accounts on
        the public accounts tab
parity --help
Usage:
  parity [options]                                        Operating Options:
  parity ui [options]                                       --mode MODE
  parity dapp  [options]                              --mode-timeout SECS
  parity daemon  [options]                        --mode-alarm SECS
  parity account (new | list ) [options]                    --auto-update SET
  parity account import ... [options]                 --release-track TRACK
  parity wallet import  --password FILE [options]     --no-download
  parity import [  ] [options]                        --no-consensus
  parity export (blocks | state) [  ] [options]       --force-direct
  parity signer new-token [options]                         --chain CHAIN
  parity signer list [options]                              -d --base-path PATH
  parity signer sign [  ] [ --password FILE ] [options  --db-path PATH         ]
  parity signer reject  [options]                       --keys-path PATH
  parity snapshot  [options]                          --identity NAME
  parity restore [  ] [options]
  parity tools hash 
  parity db kill [options]

UI Options:                API and Console Options:   Secret Store Options:
  --force-ui                 --no-jsonrpc               --no-secretstore
  --no-ui                    --jsonrpc-port PORT        --secretstore-port PORT
  --ui-port PORT             --jsonrpc-interface IP     --secretstore-interface IP
  --ui-interface IP          --jsonrpc-cors URL         --secretstore-path PATH
  --ui-path PATH             --jsonrpc-apis APIS
  --ui-no-validation         --jsonrpc-hosts HOSTS   Snapshot Options:
                             --no-ipc                  --at BLOCK
Networking Options:          --ipc-path PATH           --no-periodic-snapshot
  --no-warp                  --ipc-apis APIS
  --port PORT                --no-dapps              Virtual Machine Options:
  --min-peers NUM            --dapps-port PORT         --jitvm
  --max-peers NUM            --dapps-interface IP
  --snapshot-peers NUM       --dapps-hosts HOSTS
  --nat METHOD               --dapps-cors URL        Internal Options:
  --network-id INDEX         --dapps-user USERNAME     --can-restart
  --bootnodes NODES          --dapps-pass PASSWORD
  --no-discovery             --dapps-path PATH       Miscellaneous Options:
  --node-key KEY             --dapps-apis-all          -c --config CONFIG
  --reserved-peers FILE      --ipfs-api                -l --logging LOGGING
  --reserved-only            --ipfs-api-port PORT      --log-file FILENAME
  --allow-ips FILTER         --ipfs-api-interface IP   --no-config
  --max-pending-peers NUM    --ipfs-api-cors URL       --no-color
  --no-ancient-blocks        --ipfs-api-hosts HOSTS    -v --version
                                                       -h --help
Sealing/Mining Options:     Footprint Options:
  --author ADDRESS            --tracing BOOL
  --engine-signer ADDRESS     --pruning METHOD        Account Options:
  --force-sealing             --pruning-history NUM     --unlock ACCOUNTS
  --reseal-on-txs SET         --pruning-memory MB       --password FILE
  --reseal-min-period MS      --cache-size-db MB        --keys-iterations NUM
  --work-queue-size ITEMS     --cache-size-blocks MB    --no-hardware-wallets
  --tx-gas-limit GAS          --cache-size-queue MB
  --tx-time-limit MS          --cache-size-state MB
  --relay-set SET             --cache-size MB
  --usd-per-tx USD            --fast-and-loose
  --usd-per-eth SOURCE        --db-compaction TYPE
  --price-update-period T     --fat-db BOOL
  --gas-floor-target GAS      --scale-verifiers
  --gas-cap GAS               --num-verifiers INT
  --extra-data STRING
  --tx-queue-size LIMIT        Import/Export Options:
  --tx-queue-gas LIMIT           --from BLOCK
  --tx-queue-strategy S          --to BLOCK
  --tx-queue-ban-count C         --format FORMAT
  --tx-queue-ban-time SEC        --no-seal-check
  --no-persistent-txqueue        --at BLOCK
  --remove-solved                --no-storage
  --notify-work URLS             --no-code
  --refuse-service-transactions  --min-balance WEI
  --stratum                      --max-balance WEI
  --stratum-interface IP
  --stratum-port PORT
  --stratum-secret STRING
Running
Non-Docker, simplest way with all defaults:
$ ./target/release/parity
SystemD integration
$ cp .../parity/scripts/parity.service ~/.config/systemd/user
     To pass any argument to Parity edit
     ARGS line at ~/.parity/parity.conf like:
     ARGS="ui --identity MyMachine"
Docker Launch
$ sudo docker run -v /var/myProject/data_parity:/data_parity
  -p 30303:30303 -p 8545:8545 -p 8546:8546 --rm -ti
  parity/parity:v1.6.10
  ui
  --jsonrpc-port 8545 --jsonrpc-interface all --jsonrpc-hosts all
  --port 30303
  --min-peers 0 --max-peers 0 --no-discovery
  --chain /data_parity/dev.json
  --db-path /data_parity
  --author 0xa311aa60e1013bf7145454b015dda7399264c6af
  --tx-queue-size 1
  --tx-gas-limit 2100000000000000
  --usd-per-tx 0.0005 --usd-per-eth 200
  --gas-floor-target 21000
  --cache-size 2048 --db-compaction hdd
  -lchain,client,engine,estimate_gas,ethash,miner=trace --no-color
dev.network
(Instant shield)
@[https://github.com/paritytech/parity/wiki/Private-development-chain]
Edit ...*/data_parity/dev.json* like:
{
    "name": "localNetwork",
    "engine": {
        "instantSeal": { "params" : {} }
    },
    "params": {
        "accountStartNonce": "0x0100000",
        "maximumExtraDataSize": "0x20",
        "minGasLimit": "0x1388",
        "networkID" : "${CHAIN_ID}"
    },
    "genesis": {
        "seal": {
            "generic": "0x0"
        },
        "difficulty": "0x20000",
        "author": "0x0000000000000000000000000000000000000000",
        "timestamp": "0x00",
        "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "extraData": "0x",
        "gasLimit": "0x5B8D80000000000000000000"
    },

    "nodes": [ ],
    "accounts": {
        "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
        "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
        "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
        "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
        "0x${PUB_ADDRESS_1}"                        : { "balance": "1000000000000000000000", "nonce": "1048576"  }
    }
}

- Launch parity with the option:
  --chain */data_parity/dev.json*
EEA
External Links
@[https://entethalliance.org/]
@[https://www.goquorum.com]
Tech.documents           @[https://entethalliance.org/technical-documents/]
                         - EEA Client Spec
                         - EEA Off-Chain Trusted Compute Spec
                         - EEA Architecture Stack
                         - ....
Collaboration site       @[https://member.entethalliance.org/communities-all-members60/librarydocuments]
Youtube Channel          @[https://www.youtube.com/channel/UClC49LtcE4Wuo4POqa4J0bA]


  EEA Summary
[P]SMRT-030:Enterprise Ethereum clients MUST support
   smart contracts of at least 24,576bytes in size
[P]SMRT-040:Enterprise Ethereum clients MUST read and enforce a size limit
   for smartcontracts from the current network configuration (e.g. the genesis
   block).
[P]SMRT-050: If no contract size limit is specified in a genesis block,
   subsequent hard fork blockor network configuration, Enterprise Ethereum
   clients MUST enforce a size limit on smartcontracts of 24,576 bytes.

- Permissioning is the property of a system that ensures operations are
  executed by and accessible todesignated parties. For Enterprise Ethereum,
  permissioning refers to:
  - the ability of a node to join an Enterprise Ethereum blockchain
  - the ability of individual accounts or nodes to perform
    specific functions.
  - Ex: an Enterprise Ethereum blockchain might only allow certain nodes
    to act as validators, and only certain accounts to instantiate smart
    contracts.Enterprise Ethereum provides a permissioned implementation
    of Ethereum supporting peer nodeconnectivity permissioning,
    account permissioning, and transaction type permission.

7.1.1 Nodes:
  [C] NODE-010:Enterprise Ethereum implementations MUST provide the ability
      to specify atstartup a list of static peer nodes to establish
      peer-to-peer connections with.
  [C] NODE-020:Enterprise Ethereum clients MUST provide the ability to enable
      or disable peer-to-peer node discovery.
  [P] NODE-030:Enterprise Ethereum clients MUST provide the ability to specify
      a whitelist of thenodes permitted to connect to a node.
  [P] NODE-040:Enterprise Ethereum clients MAY provide the ability to specify
      a blacklist of thenodes not permitted to connect to a node.7.1 Permissions
      and Credentials Sublayer
  [P] NODE-050: It MUST be possible to specify the node whitelist required by
      NODE-030 througha transaction into a smart contract.
  [P] NODE-060: It MUST be possible to specify the node blacklist allowed by
      NODE-040 (ifimplemented) through a transaction into a smart contract.
  [P] NODE-080:Enterprise Ethereum clients MUST provide the ability to specify
      node identities ina way aligned with the concept of groups.
  [P] NODE-090:Enterprise Ethereum clients MUST document which metadata parameters
      (if any)can affect transaction ordering, and what the effects are.
Net Protocol Sublayer
(enodes, ...)
- Nodes MUST be identified and advertised using the
  Ethereum enode URL format
- Implementations SHOULD use the DEVp2p Wire Protocol
  for messaging between nodes to establish and maintain a
  communications channel for use by higher layer protocols.

- These higher layer protocols are known as capability protocols

- The Ethereum-Wire-Protocol defines the capability
  protocols for messaging between Ethereum client nodes to
  exchange status, including block and TX info.

- messages are sent and received over an already
  established DEVp2p connection between nodes.

- Implementations SHOULD support, at a minimum,
  Ethereum-Wire-Protocols eth/62 and eth/63

- Implementations MAY add new protocols or extend
  existing Ethereum protocols

- To minimize the number of point -to-point connections
  needed between private nodes , some private nodes
  SHOULD be capable of relaying private TX data to
  multiple other private nodes.
Design Considerations
- Private contracts cannot update public contracts.
  (not all participants will be able to execute a private contract,
  and so if that contract can update a public contract, then each
  participant will end up with a different state for the public contract.
- Once a contract has been made public, it can't later be made private.
  You DO need to delete from the blockchain and create a new private contract
Supported Consensus
- Probe of Authority (PoA):
  @[https://github.com/ethereum/EIPs/issues/225]
  @[https://github.com/ethereum/go-ethereum/blob/master/consensus/clique/clique.go]
  @[https://github.com/NethermindEth/nethermind/tree/master/src/Nethermind/Nethermind.Clique]
  @[https://github.com/hyperledger/besu/tree/master/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique]
  - TestNet:
  @[https://github.com/goerli/testnet]  @[https://goerli.net/]
  """Görli Testnet is the first proof-of-authority cross-client testnet, synching Parity Ethereum, Geth, Nethermind,
  Pantheon, and EthereumJS."""

- RAFT:
- IBFT: (Istambul) Bizantine Fault Tolerant
IBFT
(Istambul)BFT
@[https://github.com/ethereum/EIPs/issues/650]
- Target banks and fin.instutions, replacing PoW
  since validator scalability is not required.
- Hash settlement finality and minimum latency.
- Deeply inspired by Clique PoA @[https://github.com/ethereum/EIPs/issues/225]
- also inspired by Hyperledger's SBFT, Tendermint, HydraChain, and NCCU BFT.

Validator  : Block validation participant.
Proposer   : A block validation participant that is chosen
             to propose block in a consensus round.
Round      : Consensus round. A round starts with the proposer creating
             a block proposal and ends with a block commitment or round change.
Proposal   : New block generation proposal which is undergoing consensus processing
Sequence   : Sequence number of a proposal. A sequence number should be greater than
             all previous sequence numbers. Currently each proposed block height is its
             associated sequence number.
Backlog    : The storage to keep future consensus messages due to the async nature of the
             network.
Round state: Consensus messages of a specific sequence and round, including pre-prepare
             message, prepare message, and commit message.
Consensus
      proof: The commitment signatures of a block that can prove the block has gone
             through the consensus process.
Snapshot   : The validator voting state from last epoch


ºVALIDATION ROUND LOOPº
[validators] → [validators]:  enter ºvalidator.state NEW-ROUNDº
[validators] → [validators]:  pick one (round-robin by default or sticky) as
                              the OºPROPOSERº
OºPROPOSERº  →OºPROPOSERº  :  propose new block proposal
OºPROPOSERº  →  network    :  broadast Bºblock-proposal + PRE-PREPARE messageº
[validators] → [validators]:  enter ºvalidator.state PRE-PREPAREDº
[validators] → network     :  broadcast BºPREPARE messageº
                              (make sure all validators are working on the
                               same sequence and the same round)
[validators] → [validators]:Bºwait for (2F + 1) PREPARE messagesº
                              then enter ºvalidator.state PREPAREDº
[validators] → network     :  broadcasts BºCOMMIT messageº.
                              (inform peers that validator accepts proposed block
                              and is going to insert the block to the chain)
[validators] → [validators]:Bºwait for (2F + 1) COMMIT messagesº
                              enter ºvalidator.state COMMITTEDº
                              insert the block to the chain
                              enter ºvalidator.state FINAL-COMMITTEDº
[validators] → network     :  broadcasts BºROUND-CHANGE messageº
[validators] → [validators]:Bºwait for (2F + 1) ROUND-CHANGE messagesº
                              then enter ºvalidator.state NEW-ROUNDº


ºRUNNING ISTANBUL BFT VALIDATORS&NODES:º
| $ geth  --datadir "/eth" init "/eth/genesis.json"                  // ← Initialize the data folder as (PRE-SETUP)
| $ geth --datadir "/eth" --mine --minerthreads 1 --syncmode "full"  // ← Start-up validators
| $ geth --datadir "/eth"                                            // ← Start-up regular nodes

ºISTANBUL OPTIONS:º                                                                           |ºgenesis.jsonº
| --istanbul.requesttimeout value  round in milliseconds (default: 10000)                     |- config field is required, and the pbft subfield must present. Ex:
| --istanbul.blockperiod    value  Default min.difference between two consecutive             |- See also genesis.json helper tools at:
|                                  block's timestamps in seconds (default: 1)                 |@[https://github.com/getamis/Istanbul-tools]
                                                                                              |{
ºNODEKEY AND VALIDATORº                                                                       |  "config": {
|To be a validator, a node needs to meet the following conditions:                            |    "chainId": 2016,
|- Its account (nodekey-derived) address MUST be listed in extraData's validators section     |    "istanbul": { "epoch": 30000, "policy" 0 }
|- validator nodekey is used as priv.key to sign consensus messages                           |  },
                                                                                              |  "timestamp": "0x0",
ºEncoding:º                                                                                   |  "parentHash": "0x000...000",
|Before encoding you need to define a toml file with vanity and validators fields             |  "extraData": "0x0000...000f89af85494475...aad0312b84100000...0c0",
|to define proposer vanity and validator set. Please refer to example.toml for                |  "gasLimit": "0x47e7c4",
|the example. The output would be a hex string which can be put into extraData                |  "mixhash": "0x6374...6e6365",
|field directly.  Command:                                                                    |  "coinbase": "0x333...33333",
|  $ istanbul encode --config ./config.toml                                                   |  "nonce": "0x0",
                                                                                              |  "difficulity": "0x0",
ºDecoding:º                                                                                   |  "alloc": {}
|Use --extradata option to give the extraData hex string. The output would show               |}
|the following if presents: vanity, validator set, seal, and committed seal.
|Command:
|$ istanbul decode --extradata ˂EXTRA_DATA_HEX_STRING˃
|to define proposer vanity and validator set. Please refer to example.toml for
|the example. The output would be a hex string which can be put into extraData
|field directly.  Command:
|  $ istanbul encode --config ./config.toml
Raft-based consensus
@[https://github.com/jpmorganchase/quorum/blob/master/raft/doc.md]
$ geth --raft
NON  BYZANTINE FAULT TOLERANCE with next advantages:
  - faster blocktimes (milliseconds vs seconds)
  - absence of forking
  - Compared with QuorumChain, does NOT "unnecessarily" create empty blocks

+-----------+----------------+-------------------------------------------------+
|Transport  | Ethereum p2p   |  Raft (over HTTP)                               |
|Layer      |                |                                                 |
+-----------+----------------+-------------------------------------------------+
|DATA TYPE  | communicate TXs|  communicate full blocks                        |
+-----------+----------------+-------------------------------------------------+
|config     |                | Minting blocks frequency:  ˂ = 50ms ,           |
|params     |                |    (--raftblocktime (millisecs)                 |
|           |                | --raftport newTCPPort default to 50400 )        |
|           |                |                                                 |
|           |                |  static-nodes.json: required                    |
|           |                |  - initial list of nodes in the cluster         |
|           |                |  - order ºMUST BE EQUALS ACROSS PEERSº          |
|           |                |                                                 |
|           |                | - ID URIs must include a raftport querystring   |
|           |                |   param specifying the raft port for each peer: |
|           |                |   e.g.                                          |
|           |                |    enode://abcd@127.0.0.1:30400?raftport=50400  |
+-----------+----------------+-------------------------------------------------+

removing a node from the cluster from the JS console:
# raft.removePeer(raftIdx)
                  ^
                  "1-indexed" index in the static peer list

Attaching a node to the cluster from the JS console:

# raft.addPeer("enode://abcd@127.0.0.1:30400?raftport=50400")
Then (outside the JS console) start the new geth node with the
flag --raftjoinexisting RAFTID in addition to --raft
TX Manager
  - Quorum’s Transaction Manager is responsible for Transaction privacy.
     It stores and allows access to encrypted transaction data, exchanges encrypted
     payloads with other participant's Transaction Managers but does not have
     access to any sensitive private keys. It utilizes the Enclave for
     cryptographic functionality (although the Enclave can optionally be
     hosted by the Transaction Manager itself.)

  - """To send a private transaction, a PrivateTransactionManager must be
     configured. This is the service which transfers private payloads to
     their intended recipients, performing encryption and related operations
     in the process."""
  - The Transaction Manager is restful/stateless and can be load balanced easily.

Transaction Processing
  - 'Public Transactions' and 'Private Transactions' are a notional concept
    only and Quorum does not introduce new Transaction Types, but rather, the
    Ethereum Transaction Model has been extended to include an optional
    'OºprivateForº' parameter (the population of which results in a Transaction
    being treated as private by Quorum) and the Transaction Type has a new
    IsPrivate method to identify such Transactions.
  - OºprivateForº can take multiple addresses in a comma separated list.
  - Private Transactions payload is only visible to the network
    participants specified in the OºprivateForº parameter of the TX.
  - Quorum Node sets the Transaction_Signature.V = 37 or 38
    (as opposed to 27 or 28)

  - prior to propagate the TX to the rest of the network,
    mining/sender node replaces the original TX-Payload with
    a the hash of the encrypted Payload that received from the
    secure enclave implementation (Crux, Constellation,..).
    Participants involved in the OºprivateForº TX
    will have the encrypted payload associated to the hash
    within their secure enclave.

  Example priv.TX A←→B:
Party A and B belongs to TX AB, whilst C doesn't
Party A → A.Node: TX + payload
                TX.OºprivateForº [ pub.key A, pub.keyB]
A.Node → A TX Manager: Request to store TX payload
A_TX_Manager → Enclave: - Validate sender with A priv.key

Enclave → Enclave:  performs TX conversion (encrypt payload)
                    - generating [sym.key, random Nonce]
                    - encrypting TX.payload+Nonce with sym.key
                    - generate hash  SHA3-512 (encrypted payload)
                    - iterate through TX recipients [A, B] encrypting
                      sym.key with recipient's pub.key (PGP encryption)
A_TX_Manager ← Enclave: encrypted payload, SHA3-512 hash, encrypted keys
A_TX_Manager → A_TX_Manager: store encrypted payload, encrypted sym.key
                             (using hash as index)
A_TX_Manager → B_TX_Manager: (via HTTPS) hash, encrypted (payload, sym.key)
A_TX_Manager ← B_TX_Manager: Ack
A.Node ←  A_TX_Manager: SHA3-512 (encrypted payload)
A.Node →  A.Node: - Replace TX.payload with TX.sha3-512
                  - changes TX.V to 37 or 38 (indicates other nodes that
                    hash represents priv.TX)
A_TX_Manager → Network:  (Ethereum P2P protocol) TX encrypted payload
Network → Network: +block containing TX AB
Network → Node N: block containing TX AB
Node N → Node N: Try validate TX in block
                 - Recognise TX.V is 37 or 38
Node N → Node N TX_Manager: Do nodes holds private TX?
Node N ← Node N TX_Manager: YES  (continue validation)
                         or "NotARecipient" (skip to next TX in block)
A,B Node → A,B enclave: TX payload
           A,B enclave: 1. validates signature
                        2. decrypts sym.key  private key that is held
                           in The Enclave, decrypts the Transaction Payload using
                           the now-revealed symmetric key and returns the decrypted
                           payload to the Transaction Manager.
A,B TX_Manager → A,B EVM: send decrypted payload
A,B EVM → A,B EVM: contract code execution
                   Update Quorum Node's Private StateDB only.
                   NOTE: code discarded once executed.
Secure Enclave
 - Distributed Ledger protocols typically leverage cryptographic techniques
   for transaction authenticity, participant authentication, and historical
   data preservation (i.e. through a chain of cryptographically hashed data
   .) In order to achieve a separation of concerns, as well as to provide
   performance improvements through parallelization of certain crypto-
   operations, much of the cryptographic work including symmetric key
   generation and data encryption/decryption is delegated to the Enclave.
 - The Enclave works hand in hand with the Transaction Manager to
   strengthen privacy by managing the encryption/decryption in an isolated
   way. It holds private keys and is essentially a “virtual HSM” isolated
   from other components.
 - Different implementations of the enclave exists:
   - Constellation: Original, writen in Haskell
   - Crux         : Golang based, compatible with Constellation
JS client privateFor ex.
"privateFor": indicates the list of constellation (vs Ethereum) public keys
              of TX recipient. If not empty the TX will be private.
web3.eth.defaultAccount = eth.accounts[0];
var simpleSource = 'contract simplestorage { ... }'
var simpleCompiled = web3.eth.compile.solidity(simpleSource);
var simpleRoot = Object.keys(simpleCompiled)[0];
var simpleContract = web3.eth.contract(
    simpleCompiled[simpleRoot].info.abiDefinition);
var simple = simpleContract.new(42,
    {from:web3.eth.accounts[0],
     data: simpleCompiled[simpleRoot].code,
     gas: 300000,
     privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="]
    }, function(e, contract) {
      if (e) { throw("err creating contract", e); }
      if (!contract.address) {
        console.log(contract.transactionHash + " mining...");
        return;
      }
      console.log("Contract Address: " + contract.address);
    });
  Plugable EVM spec
@[https://ethereum.github.io/evmc/]
@[https://github.com/ethereum/evmc]

- Allows to "plug-in" different EVM implementations.

- The EVMC is the low-level ABI between Ethereum Virtual Machines (EVMs) and
  Ethereum Clients. On the EVM side it supports classic EVM1 and ewasm. On the
  Client-side it defines the interface for EVM implementations to access
  Ethereum environment and state.

- It's currently used by the evmone project. (@[https://github.com/chfast/evmone])
  Potentially
  A Java-to-Native (JNI) wrapper looks to exists:
@[https://github.com/semuxproject/evmc-jni]
  See also:
@[https://github.com/jnr/jnr-ffi]
  - Java library for loading native libraries without writing JNI code by hand

evmONE
(100x faster!!)
- EVM implementation
-@[https://github.com/ewasm/benchmarking]
EEA DevOps
  enode HowTo
  
Extracted from rlpx.md
"""
 Oº(P2P Network) NODE Identity:º
   each node is expected to maintain a staticOºsecp256k1 private keyº
   which is saved and restored between sessions.
   It is recommended that the private key can only be reset manually,
   for example, by deleting a file or database entry.

   There are two kinds of connections which can be established.
   A node can connect to:
     ─ a known peer which has previously been connected to
       and from which a corresponding session token is available for
       authenticating the requested connection
     ─ a new peer
"""
- enode uri scheme is used by theºNode discovery protocolº
- enode uri scheme can be used in the bootnodes command line option                                                                      RºWARN:º
  of the client or as the argument to suggestPeer(nodeURL) function                                                                      RºDNS names are NOT allowed  º
  in the JSRE.                                                                                                                           Rº(Only IP addresses to avoidº
                                                                                                                                         RºDNS based attacks)         º
                                                                                                                                         └───────┬───────────────────┘
                                                                                                                                                 │
Extracted from: ethereum-wiki
                                               ┌────┴────────┐
enode://Bº6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0º@10.3.58.6:30303?discport=30301
        Bº└─────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────┘º                └─────┬──────┘
        Bº                                                  │                     º                                                                              │
        Bº                                                  │                     º                                                                              │
        Bº                   64-bytes hexadecimal encoded node ID representing theº                                                                          UDP port used
        Bº                   secp256k1 public key                                 º                                                                          for discovery
        Bº                   corresponding to node's private key                  º                                                                          (default to
                                                                                                                                                           the TCP port)
º(DevOps) GENERATE PRIVATE KEY AND ENODE ID:º
(REF:@[https://kobl.one/blog/create-full-ethereum-keypair-and-address/])

ºSTEP 1: Generate private keyº
$ºopensslºecparam -name secp256k1 -genkey -noout | tee ˃OºnodePrivateKeyº
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIGLW3b7sUpzhb3I4/sLCbakIjfUz6KuBh3Xaox62beJ3oAcGBSuBBAAK
oUQDQgAEUarn9mq43dODnfxAVcSksAxHsTbrco9FnV0A7Mzqr6guzCQlCCmgXM7k
Kns43IkR1JfB8mwKkTfOPdykq9nGIg==
-----END EC PRIVATE KEY-----

ºSTEP 2: Show associated public-key in enode format (64 bytes hex-encoded)º
$ catOºnodePrivateKeyº |ºopensslºec -noout -text                             | grep pub -A 5 | tail -n +2 | tr -d '\n[:space:]:' | sed 's/^04//'
                         ^^^^^^^^^^^^^^^^^^^^^^^^                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       - Display info with public key                         - Convert public key to enode expected format (64bytes hex-encoded)
                       - Output will be similar to:                           - Output will be similar to:
                         Private-Key: (256 bit)                              Bº067434d510e3e186a039583db727cd8d3daee9fc238a6d542eca03b0b7bc8528df9b4d878661f350c0ea3d5337a5831c94d84e22c5baffee7a55e9cb1f808e06º
                       Oºpriv:                                            º
                       Oº    00:f4:16:f5:89:3d:60:86:8a:1d:77:4d:2f:74:3b:º
                       Oº    29:53:5b:b9:cb:f9:50:0e:38:39:24:c5:7a:a9:1b:º
                       Oº    b7:d2:b4                                     º
                       Bºpub:                                             º
                       Bº    04:06:74:34:d5:10:e3:e1:86:a0:39:58:3d:b7:27:º
                       Bº    cd:8d:3d:ae:e9:fc:23:8a:6d:54:2e:ca:03:b0:b7:º
                       Bº    bc:85:28:df:9b:4d:87:86:61:f3:50:c0:ea:3d:53:º
                       Bº    37:a5:83:1c:94:d8:4e:22:c5:ba:ff:ee:7a:55:e9:º
                       Bº    cb:1f:80:8e:06                               º
                         ASN1 OID: secp256k1

ºSTEP 3: Get Public Address from public key (keccak-256sum of public address)º
$ cat Bº${publicAddres} | | keccak-256sum -x -l | tr -d ' -' | tail -c 41
0bed7abd61247635c1973eb38474a2516ed1d884
 1 2 3 4 5 6 7 8 9 0 2 3 4 5 6 7 8 9 0 1
                   1                 2               
PKCS-friendly Wallet
@[https://kobl.one/blog/create-full-ethereum-keypair-and-address/]
@[https://github.com/maandree/sha3sum] C implementation

 ºINPUTº        → ºTOOLSº     →  ºOUTPUTº 
  "/dev/random"    - OpenSSL      - ECDSA private key
                   - sha3sum      - Ethereum address

WARN:
SHA3 != keccak (Ethereum keccak-256) 
More info at:
@[https://ethereum.stackexchange.com/questions/550/which-cryptographic-hash-function-does-ethereum-use]


STEP 1: Generate EC private key


This command will print the private key in PEM format (using the wonderful ASN.1 key structure) on stdout. If you want more OpenSSL info on elliptic curves, please feel free to dig further.

$ openssl ecparam        -name secp256k1 -genkey -noout  > /tmp/privateKey01
          ^^^^^^^              ^^^^^^^^^                  ^^^^^^^^^^^^^^^^^^ 
      create Ellip.Curve      secp256k1 curve             ASN encoded in base64
          private key         (Same as Bitcoin)

  → -----BEGIN EC PRIVATE KEY-----
  → MHQCAQEEIFDLYO9KuwsC4ej2UsdA4SYk7s3lb8aZuW+B8rjugrMmoAcGBSuBBAAK
  → oUQDQgAEsNjwhFoLKLXGBxfpMv3ILhzg2FeySRlFhtjfi3s8YFZzJtmckVR3N/YL
  → JLnUV7w3orZUyAz77k0ebug0ILd1lQ==
  → -----END EC PRIVATE KEY-----

$ cat /tmp/privateKey01 | openssl ec -text -noout > /tmp/splitedKey01
                                  ^^^^^^^^                                      
                             display private+public key in
                             hexadecimal format
  → read EC key
  → Private-Key: (256 bit)
  → priv:
  →     20:80:65:a2:47:ed:be:5d:f4:d8:6f:bd:c0:17:13:  ←─┐
  →     03:f2:3a:76:96:1b:e9:f6:01:38:50:dd:2b:dc:75:    │
  →     9b:bb                                            │
  → pub:                                                 │
  →     04:83:6b:35:a0:26:74:3e:82:3a:90:a0:ee:3b:91:    │
  →     bf:61:5c:6a:75:7e:2b:60:b9:e1:dc:18:26:fd:0d:    │
  →     d1:61:06:f7:bc:1e:81:79:f6:65:01:5f:43:c6:c8:    │
  →     1f:39:06:2f:c2:08:6e:d8:49:62:5c:06:e0:46:97:    │
  →     69:8b:21:85:5e                                   │
  → ASN1 OID: secp256k1                                  │
  ┌──────────────────────────────────────────────────────┘
  │
  └─ Remove any null byte (0x00) in front of the private part,
     (this happens "sometimes"). Priv.key length must be 32 bytes

     Uncompressed Public key length must be 64 bytes long 
     (65 with the ºconstant 0x04 prefixº)

STEP 2: Extract the public key and format properly for keccak-256:
$ cat /tmp/splitedKey01 | grep pub -A 5 | tail -n +2 | 
            tr -d '\n[:space:]:' | sed 's/^04//' \
  > /tmp/pubKey01
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 (example script to extract the 64 bytes in a row)
   
 Output (/tmp/pubKey01) must look similar to:
 836b35a026743e823a90a0ee3b91bf615c6a757e2b60b9e1dc1826fd0dd16106f7bc1e8179f665015f43c6c81f39062fc2086ed849625c06e04697698b21855e
 (hexadecimal representation of the 64 bytes)

STEP 3: Calculate Ethereum address as:

$ cat /tmp/pubKey01 | keccak-256sum -x -l | tr -d ' -' | tail -c 41 
                                    ^^      ^^^^^^^^^^^^^^^^^^^^^^^ 
                            Input are hex   keep only the last 20 bytes 
                            char(vs string) (get rid of first 12).
                                            20bytes = 40chars (+1 line return)

  Output will be similar to
  → 0bed7abd61247635c1973eb38474a2516ed1d884
    0         1         2         3
     123456789 123456789 123456789 123456789

RºCAUTION!: if final address looks like 
    *0xdcc703c0E500B653Ca82273B7BFAd8045D85a470* this means you
     have hashed an empty public key. Sending funds to this
     address will lock them forever!

STEP 4: (Optional) Import private key to geth
# Extract the private key and remove the leading zero byte
$ geth account import priv "privateKey_hexFormat_no_leading_00"
Passphrase: 
Repeat passphrase: 
Address: {0bed7abd61247635c1973eb38474a2516ed1d884}

You're now ready to use the new account with geth. Of course, 
it would be easier to take advantage of the geth account new feature 
in order to quickly setup an Ethereum account. But manually doing
it gives you the power of knowing your public and unencrypted 
private keys. In addition, this would be useful to generate a
secure Ethereum account completely off chain.
PUPPETH
@[https://www.youtube.com/watch?v=T5RcjYPTG9g] ºPUPPETHº For easy deployment of networks
- Integrated into Geth 1.9+

-B*high value production tool aiding to create a new Ethereum network
  ºdown to the genesis block:º
 Bºbootnodes, signers, ethstats, faucet, wallet, explorer and dashboard.º

- Originally created to support the Rinkeby testnet, now is a high value
  production tool.
  See also @[https://www.youtube.com/watch?v=T5RcjYPTG9g]

- Geth v1.9.0 ships a preliminary integration of Blockscout into Puppeth.
 ºBlockscout, a real, open source block explorer, courtesy of the POA Network teamº
 filling a huge hole in our private network deployment tool!
R*WARN: initial integration (e.g. due to a “bug” in Blockscout, the Puppeth
        explorer will need to fully sync a Geth archive node before it can boot up
        the explorer web interface).
Clef
@[https://github.com/ethereum/go-ethereum/blob/master/cmd/clef/tutorial.md]
Clef can be used to sign transactions and data and is meant as a(n eventual) 
replacement for Geth's account management. This allows DApps to not depend on 
Geth's account management. When a DApp wants to sign data (or a transaction), 
it can send the content to Clef, which will then provide the user with 
context and asks for permission to sign the content. If the users grants the 
signing request, Clef will send the signature back to the DApp.
Kaleido (SaaS Besu)
External Links
-@[https://docs.kaleido.io/getting-started/about-kaleido/]
-@[https://github.com/kaleido-io/]
Marketplace
@[https://marketplace.kaleido.io/]
- Zero Knowledge Token Transfer
- Token Swap: Easily and securely trade tokens with other members in your environment.
- Document Store: Store, manage and share information from your own private document store 
- App2App Messaging
  - Communicate securely and reliably with end-to-end encrypted messaging from Dapp to Dapp
  - Identity and Access Management (IAM)
    Integrate your existing enterprise identity management with your Dapp
- Rotate signers
  Scale IBFT consensus algorithm for broader participation
- Token Explorer Dashboard
- EthWallet
  Simple and secure way to manage key ownership for signing transactions.
- HD Wallet
  Submit transactions anonymously, mask your identity + manage accounts]
- IPFS File Store
  Securely store data through a censorship resistant file sharing protocol
- On-Chain Registry
  Bind verified digital certificates to org Ethereum addresses via on-chain registry
- Public Ethereum Tether
  Pin state proofs from your private chain to public Ethereum networks
- Connectors
  - If This Then That (IFTTT)
    - Automate workflows and exchange data to and from the chain with the IFTTT connector
  - Zapier
    - Automate workflows and exchange data to and from the chain with any Zapier app connection
  - Salesforce
    - Exchange chain data to and from your Salesforce CRM and applications
- Middleware
  - Event Streams: 
    Trigger business processes, and stream data to off-chain caching or analytics
  - REST API Gateway
    APIs for all your Smart Contracts, backed by reliable Kafka streaming
- Partner Integrations
  - QEDIT Private Asset Transfer
    Keep sensitive transactional data off the blockchain with zero-knowledge proof cryptography.
  - Openlaw
    Create, store and execute legal agreements for blockchain assets
  - Treum
    Model business processes, track assets + build supply chains faster
  - unchain.io
    Interact with an Ethereum smart contract on Kaleido via a simple API
  - Clause
    Store audit trail events from your Smart Clauses (TM) on your Kaleido blockchain.
  - Chainlink
    Provide external data to Ethereum smart contracts via oracle network
  - Rhombus
    Connect your smart contract with real-world data

- Developer Tools
  - MythX: Premier security analysis service for Ethereum smart contracts
  - Remix: Quickly and easily write, compile and debug smart contracts.
  - OpenZepplin: Reduce the risk of vulnerabilities in your applications by
    using standard, tested, community-based smart contract code.
  - MetaMask: Run dApps right in your browser without running a full Ethereum node.
  - Truffle: Truffle gets developers from idea to dapp as comfortably as possible

- Cloud Configurations
  - Amazon Web Services: Key Management backed by AWS KMS
    Create and control the keys used to encrypt your data
  - Log Streaming
    View and monitor your Kaleido resources in AWS CloudWatch
  - Backup your Ledger to AWS S3
    Backup your Ledger Data and Transactions to AWS S3 blob storage

- Federated Login:
  -  Implement simple and secure user sign-up, sign-in, and access control

- Private Networking
  Leverage secure network connectivity for sensitive data sharing
- Microsoft Azure
  - Key Protection
  - Key Management backed by Azure Key Vault
  - Log Streaming
    View and monitor your Kaleido resources in Azure Monitor
  - Data Backup
    -Backup your Ledger Data and Transactions to Azure blob storage

- Protocols: Geth, Quorum, Besu
Network Gobernance
Kaleido Account
@[https://docs.kaleido.io/using-kaleido/accounts-pricing]
- parent resource used to manage "super user" actions
  not related to the application:
  - organizational identity
  - shared administrators
  - consortia collaborators
  - uploaded certificates
  - administrative bearer tokens
  - current plan instance and billing orchestration.
Developer Material
- @[https://docs.kaleido.io/developer-materials/api-101/]
- @[https://console-eu.kaleido.io/]
- @[https://github.com/kaleido-io/kaleido-js]   NodeJS example (Offline TX signing in Azure,...)
Deploy in 10 minutes
@[https://medium.com/coinmonks/deploy-a-private-ethereum-blockchain-in-10-minutes-with-kaleido-73c21a26d5bb]
Truffle←→Kaleido
@[https://medium.com/coinmonks/connecting-to-kaleido-private-ethereum-blockchain-with-truffle-7ae7cc6a3234]

ºPRE-SETUP 1: Deploy a private Kaleido Blockchain instance:º
@[https://medium.com/coinmonks/deploy-a-private-ethereum-blockchain-in-10-minutes-with-kaleido-73c21a26d5bb]

ºPRE-SETUP 2: Write down the publicpublic key from any walletº

ºPRE-SETUP 3: Truffle Framework setupº
$ npm install -g -production windows-build-tools  (Windows OS only)
$ npm install -g truffle
$ npm install truffle-hdwallet-provider-privkey #
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              allows to sign and exec TXs by providing
              a private key that belongs to an existing
              Ethereum wallet. (generated by MetaMask,...)

$ cd ...
$ mkdir trufflekaleido
$ cd trufflekaleido

$ truffle unbox webpack # ← simplex box

ºKaleido STEP 1: Ether Poolº
- paste your public key here to receive some ETH.

ºKaleido STEP 2: Edit/Create the contractº
$ "vim" .../contracts/hello.sol
  |pragma solidity ˃=0.4.22 ˂0.6.0;
  |contract Mortal {
  |    address owner;
  |    constructor() public { owner = msg.sender; }
  |    function kill() public { if (msg.sender == owner) selfdestruct(msg.sender); }
  |}
  |
  |contract Greeter is Mortal {
  |    string greeting;
  |    constructor(string memory _greeting) public { greeting = _greeting; }
  |    function greet() public view returns (string memory) { return greeting; }
  |}

ºKaleido STEP 3.1: create truffle migration scriptº
$ "vim" .../migrations/2_deploy_contracts.js
  |var mortal = artifacts.require("./Mortal");
  |var greeter = artifacts.require("./Greeter");
  |module.exports = function(deployer) {
  |deployer.deploy(greeter, 'Jack');
  |};

ºKaleido STEP 3.2: Setup truffle-config.jsº
varBºHDWalletProvider = require("truffle-hdwallet-provider-privkey");º
constRºprivKeys = [${private_key_in_hex_format_with_NO_leading_0x}]º;
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            Ex: ["65c2d64f53211d8328c6db8e8bc22341c0f0b8d22989f40f4efd0ed55e3e3d8b"];
module.exports = {
  networks: {
    development: {
      provider: function() {
        return new BºHDWalletProvideRº(rºprivKeysº, "http://kaleido_host:port");
      },                                             ^^^^^^^^^^^^^^^^^^^^^^^^
      network_id: '*',                               In the Kaleido interface select node then:
      gas: 4700000                                 - [Connect Node] →   [VIEW DETAILS]     → input SECRET-KEY → [Submit]
    },                                                              (under Native JSON/RPC)
    ganache: { ...  },                             - Copy the CONNECTION-URL under "Auth Type -INURL" section.
  },
  mocha: { ... }
  compilers: {...}
}


ºKaleido STEP 4: compile and runº
$ truffle compile
$ truffle migrate
→ Running migration: 1_initial_migration.js
→   Deploying Migrations...
→   ... 0xbb56569292a0a5f47700f450dc8e166545308835b5fd8db7d09c00a306d83852
→   Migrations: 0xcdd5665ec87da674dc58549f2fc0bb8c514661bb
→ Saving artifacts...
→ Running migration: 2_deploy_contracts.js
→   Replacing Greeter...
→   ... 0xa3447e50d0de2a86c0325e975478399d8abe931efa6458a9deb78b0b24a89d82
→   Greeter: 0x96b9b7d5330021ed3e1ab2191482479def16c036

ºKaleido STEP 5: Testing the Contractº
$ truffle console --network development
truffle(development)˃
truffle(development)˃ Greeter.deployed().then(function(contractInstance) {contractInstance.greet().then(function(v) {console.log(v)})})
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      Greeter.deployed().then(
                        function(contractInstance) {
                           contractInstance.greet().then(
                             function(v) {console.log(v)}
                           )
                        }
                      )
Services
@[https://docs.kaleido.io/kaleido-services/]
Public Eth. Tether
Ether pool
Block Explorer
HD Wallet
IPFS
ID Registry
Eth-Connect
AWS Integration
@[https://docs.kaleido.io/aws-integrations/using-aws-integrations/]
Troubleshooting
@[https://docs.kaleido.io/support/troubleshooting/]
Quorum(JP Morgan)
External Links
WiKi                     @[https://github.com/jpmorganchase/quorum/wiki]
Quorum Setup Summary     @[https://github.com/jpmorganchase/quorum/wiki/Getting-Set-Up] (WARN: use quorum-maker)
GitHub                   @[https://github.com/jpmorganchase/quorum/tree/master/docs]
Quorum-Maker             @[https://github.com/synechron-finlabs/quorum-maker]
Whitepaper,design,..docs @[https://github.com/jpmorganchase/quorum/tree/master/docs]
Releases                 @[https://github.com/jpmorganchase/quorum/releases]
JPMorgan Quorum HomePage @[https://www.jpmorgan.com/country/ES/en/Quorum]
7 node example           @[https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes]
Quorum API               @[https://github.com/jpmorganchase/quorum/blob/master/docs/api.md]
Roadmap                  @[https://github.com/jpmorganchase/quorum/wiki/Product-Roadmap]
Slack Chat               @[https://go-quorum.slack.com/]
Official Docker Images   @[https://hub.docker.com/u/quorumengineering/]
JPMorgan Tessera
(EE TX Manager)
@[https://github.com/jpmorganchase/tessera]
- Enterprise Implementation of Quorum's transaction manager
- stateless Java system that is used to enable the encryption,
  decryption, and distribution of private transactions for Quorum.

Each Tessera node:
  - Generates and maintains a number of private/public key pairs
  - Self manages and discovers all nodes in the network (i.e. their
    public keys) by connecting to as few as one other node
  - Provides Private and Public API interfaces for communication:
    Private API - This is used for communication with Quorum
    Public  API - This is used for communication between Tessera
                  peer nodes
  - Provides two way SSL using TLS certificates and various trust
    models like Trust On First Use (TOFU), whitelist, certificate
    authority, etc.
  - Supports IP whitelist
  - Connects to any SQL DB which supports the JDBC client

Tessera Wiki
Constellation
secure enclave
@[https://github.com/jpmorganchase/constellation]
@[https://github.com/jpmorganchase/quorum/blob/master/docs/privacy.md]

  - self-managing, peer-to-peer network of "key server+PGP+MTAs" nodes
  - Constellation is not blockchain-specific, and potentially applicable
     in many other types of applications
  - Constellation's current primary application is to implement the
    "privacy engine" for Quorum Private transactions (TX with a flag indicating
    its pretended privacy and the addressable identifier )
  - Hosts a number of Private/Public key pair Curve25519 - NaCl-
  - Automatically discovers other nodes on the network after synchronizing
    with as little as one other host.
  - Synchronizes a directory of public keys mapped to recipient hosts with
    other nodes on the network.
  - Exposes public API allowing other nodes to send encrypted bytestrings to
    your node, and to synchronize, retrieving information about the nodes
    that your node knows about.
  - Exposes a private API which:
    - Allows you to send a bytestring to one or more public keys, returning
      a content-addressable identifier. This bytestring is encrypted
      transparently and efficiently (at symmetric encryption speeds) before
      being transmitted over the wire to the correct recipient nodes (and only
      those nodes.) The identifier is a hash digest of the encrypted payload
      that every receipient node receives. Each recipient node also receives a
      small blob encrypted for their public key which contains the Master Key
      for the encrypted payload.
    - Allows you to receive a decrypted bytestring based on an identifier.
      Payloads which your node has sent or received can be decrypted and retrieved
      in this way.

    - Exposes methods for deletion, resynchronization, and other management functions.

  - Supports a number of storage backends including LevelDB, BerkeleyDB, SQLite,
    and Directory/Maildir-style file storage suitable for use with any FUSE
    adapter, e.g. for AWS S3.

  - Uses mutually-authenticated TLS with modern settings and various trust
    models including hybrid CA/tofu (default), tofu (think OpenSSH), and
    whitelist (only some set of public keys can connect.)

  - Supports access controls like an IP whitelist.

ºINSTALLATIONº
Pre-Install supporting libraries:
  Ubuntu : $ apt-get install libdb-dev libleveldb-dev libsodium-dev zlib1g-dev libtinfo-dev
  Red Hat: $ dnf install libdb-devel leveldb-devel libsodium-devel zlib-devel ncurses-devel
  MacOS  : $ brew install berkeley-db leveldb libsodium

Install
  Alt 1: Precompiled binaries:
  Release download

  Alt 2: from source
    - First time only: Install Stack:
      Linux: $ curl -sSL https://get.haskellstack.org/ | sh
      MacOS: $ brew install Haskell-stack
    - First time only: run stack setup to install GHC, the Glasgow Haskell Compiler
    - Run stack install

Post-install: Generating key pair "node":
  $  constellation-node --generatekeys=node # generated keys can be locked with passwd

ºRUNNINGº
- can be run as stand-alone daemon via constellation-node, or
  imported as a Haskell library, allowing to implement custom
  storage and encryption logic.

$ constellation-node "path_to_config_file" # or use ENV.VAR
# More info at quorum/private/constellation/node.go

ºCONFIGURATION FILE FORMATº
REF
url = "http://127.0.0.1:9001/"
port = 9001
workdir = "data"
socket = "constellation.ipc"
othernodes = ["http://127.0.0.1:9000/"]
publickeys = ["foo.pub"]
privatekeys = ["foo.key"]
alwayssendto = []
storage = "dir:storage"
verbosity = 1
tls = "strict"
tlsservercert = "tls-server-cert.pem"
tlsserverchain = []
tlsserverkey = "tls-server-key.pem"
tlsservertrust = "tofu"
tlsknownclients = "tls-known-clients"
tlsclientcert = "tls-client-cert.pem"
tlsclientchain = []
tlsclientkey = "tls-client-key.pem"
tlsclienttrust = "ca-or-tofu"
tlsknownservers = "tls-known-servers"
Crux
(Constellation
alternative)
@[https://medium.com/web3labs/announcing-crux-a-secure-enclave-for-quorum-61afbfdb79e4]
- dropin Constellation replacement
- secure enclave  written in Golang (Constellation is written in Haskell)
- 7 nodes example deployment with Crux
- LevelDB used as storage (same as geth).
  BerkeleyDB bindings available for compatibility with
  existing Constellation instance.

ºBUILDº                                          ºPRE-SETUPº
$ git clone https://github.com/blk-io/crux.git   generate new keys using:
$ cd crux                                        $ cruxº--generate-keysº myKey
$ make setup ⅋⅋ make
$ ./bin/crux

ºUSSAGEº
run it like: (almost identical to Constellation node):
$ crux --url=http://127.0.0.1:9001/ \          | crux --help reference:
       --port=9001 --workdir=crux \            |     crux.config              Optional config file
       --publickeys=tm.pub \                   |     --alwayssendto string    public key List  for nodes to send all transactions to
       --privatekeys=tm.key \                  |     --berkeleydb             switch to Berkeley DB for compatibility with Constellation data store [experimental]
       --othernodes=https://127.0.0.1:9001/    |     --generate-keys string   Generate a new keypair
                                               |     --othernodes string      "Boot nodes" used to discover the network
                                               |     --port int               The local port to listen on (default -1)
                                               |     --privatekeys string     Private keys hosted by this node
                                               |     --publickeys string      Public keys hosted by this node
                                               |     --socket string          IPC socket to create for access to the Private API (default "crux.ipc")
                                               |     --storage string         Database storage file name (default "crux.db")
                                               |     --url string             The URL to advertise to other nodes (reachable by them)
                                               |     --verbosity int          Verbosity level of logs (default 1)
                                               |     --workdir string         The folder to put stuff in (default: .) (default ".")
Priv. TX Seq.
─@[https://raw.githubusercontent.com/jpmorganchase/quorum─docs/master/images/QuorumTransactionProcessing.JPG]
                                             TxPayloadRequest
                                        ┌──────────────────────────────┐
  ┌─→                                   │                              │           3,10 En/De─cryption
  │                                     │         2 TXPayloadStore ┌─────────────┐             request ┌───────────┐
  │   ┌──────┐ 1 Private TX ┌───────────────────┐                  │             ├────────────────────→│           │
  │   │ Dapp │      AB      │                   ├─────────────────→┼ Transaction │                     │ Enclave A │
 P│   └────────────────────→┼   Quorum Node A   │                  │ Manager A   │                     │           │
 A│                         │                   │                  │             │←────────────────────┴───────────┘
 R│                         │  Public  Private  │←───────────────────────────────┘  4,11 Tx Response
 T│                         │  State    State   │ 6 TX Hash          │       ^
 Y│       8 Block w/Tx AB   │  ┌────┐   ┌────┐  │                    │       │
  │        ┌──────────────→ │  ├────┤   ├────┤  │                    │       │
 A│        │                │  └────┘   └────┘  │                    │       │
  │        │                │                   │                    │       │5
  │        │                └───────────────────┘                    │       │TXPayloadStore
  │        │                    ^     ^                              │       │
  │   ┌──────────┐      7 Ether │     │ 12 TxPayloadResp (TX Payload)│       │
  └─→ │Block 123 │           TX │     └──────────────────────────────┘       │
      ├───────── │     Standard │                                            │
      │TxAB      │     Protocol │            9.TxPayloadRequest              │
      └──────────┘              │          ┌──────────────────────────┐      │
   ┌─→ │   │                    v          │                          │      v      10 En/De─cryption
   │   │   │                ┌───────────────────┐                   ┌─v───────────┐           request  ┌───────────┐
   │   │   │                │                   │                   │             ├───────────────────→│           │
 P │   │   │                │   Quorum Node B   │                   │ Transaction │                    │ Enclave B │
 A │   │   │                │                   │                   │ Manager B   │←───────────────────┤           │
 R │   │   │                │  Public  Private  │                   │             │11.Tx Response      └───────────┘
 T │   │   │                │  State    State   │                   └─────────────┘
 Y │   │   │                │  ┌────┐   ┌────┐  │                     │
   │   │   └──────────────→ │  ├────┤   ├────┤  │                     │
 B │   │ 8 Block w/Tx AB    │  └────┘   └────┘  │                     │
   │   │                    │                   │                     │
   │   │                    └───────────────────┘                     │
   │   │                       ^       ^                              │
   │   │               7 Ether │       │ 12 TxPayloadResp (TX Payload)│
   │   │                    TX │       └──────────────────────────────┘
   └─→ │              Standard │
       │              Protocol │             9.TxPayloadRequest
   ┌─→ │                       │           ┌──────────────────────────┐
   │   │                       v           │                          │
   │   │                    ┌───────────────────┐                  ┌─────────────┐                    ┌───────────┐
 P │   │                    │                   │                  │             │                    │           │
 A │   │                    │   Quorum Node C   │                  │ Transaction │                    │ Enclave C │
 R │   │ 8 Block w/Tx AB    │                   │                  │ Manager C   │                    │           │
 T │   └──────────────────→ │  Public  Private  │                  │             │                    └───────────┘
 Y │                        │  State    State   │                  └─────────────┘
   │                        │  ┌────┐   ┌────┐  │
 C │                        │  ├────┤   ├────┤  │
   │                        │  └────┘   └────┘  │
   │                        │                   │
   │                        └───────────────────┘
   │                     ^                           ^        ^                          ^
   └─→                   │                           │        │                          │
                         └───────────────────────────┘        └──────────────────────────┘
                             Ethereum standard p2p                  CONSTELLATION
                                Network Protocol                       NETWORK
EEA-Besu
(Pegasys Pantheon was renamed to Besu after joining the Hyperledger Fundation)
Chat:
@[https://chat.hyperledger.org/channel/besu]
Features
@[https://docs.pantheon.pegasys.tech/en/stable/]

- Java based, using VertX as core framework.
- Apache 2.0.
- Supports next consensus:
  - Eventual TX finality on Public Networks
    - Ethash PoW: Mainnet
    - Clique PoA: Goerli testnet
  - TX finality for private networks:
    - IBFT2: Needs 4+ nodes to really be IBFT, but fewer nodes
             are needed for "trusted" networks.
- Private TXs.
- GraphQL.
- OnChain permissioning of allowed TX-signers and allowed nodes
- OpenSource / Enterprise version.
_________________________
Extracted from old gitter channel: 2019-03-27
https://gitter.im/PegaSysEng/pantheon

Adrian Sutton @ajsutton 2019-Mar 27 22:36
"""@earizon Pantheon is designed to work for both public and private networks.
It’s not explicitly designed to be Quorum compatible, though it can sync to a
Clique or IBFT 1.0 Quorum network (but can NOT be a validator in an IBFT 1.0"
network). We do intend to support the Enterprise Ethereum Alliance spec which
I believe Quorum is also targetting to boost interoperability.  We’re still
fairly early in the benchmarking and performance improvement work for
Pantheon so I can’t put exact numbers on things.
ºCurrently Pantheon tends to be slower than Geth for syncingº
(especially since our fast sync is still under development) but is easily fast
enough to keep up with all the public networks.
Improving performance is a current focus... """

Releases
@[https://github.com/hyperledger/besu/releases]

Core Developers
@[https://github.com/hyperledger/besu/graphs/contributors?from=2019-01-07&to=2019-05-30&type=c]

ONchain Permissioning
https://docs.pantheon.pegasys.tech/en/latest/Permissions/Onchain-Permissioning/

Web3J(ava)
Integration
@[https://github.com/web3j/web3j/blob/master/besu/src/test/java/org/web3j/protocol/besu/RequestTest.java]
@[https://github.com/web3j/web3j/blob/master/besu/src/test/java/org/web3j/protocol/besu/ResponseTest.java]

Extracted from Initial Pull Request:
(@[https://github.com/web3j/web3j/pull/767]=
ºikirilovº: ... propose we reconcile common calls for geth and pantheon.
ºbenesjanº: ... There is one issue with creating common Geth and Pantheon module.
                Geth's version of minerStart accepts parameter threadCount and
                Pantheon's version does not. So unifying those two might be confusing.
ºconor10 º: ... let’s leave the duplication in for now ...


UUID: a4c55453-c75d-4faf-91aa-ae437ef80e97
ARCHITECTURE
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │                             JSON RPC                                                                                      │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 ┌────────────────────────────────────┐ ┌─────────────────────────────┐ ┌─────────────────────────────────────────────────────┐
 │              ºCOREº                │ │   ºCHAIN PROCESSING º       │ │                   ºP2Pº                             │
 │                                    │ │                             │ │                                                     │
 │  ┌───────────────────────────────┐ │ │ ┌─────────────────────────┐ │ │ ┌─────────────────────────────────────────────────┐ │
 │  │       SYNCHRONIZER            │ │ │ │    PROTOCOL SPEC        │ │ │ │               ETH SUB─PROTOCOL                  │ │
 │  │                               │ │ │ │┌──────────┐  ┌─────────┐│ │ │ │                               ┌───────────────┐ │ │
 │  │                ┌───────────┐  │ │ │ ││BLOCK     │  │TX       ││ │ │ │   ┌─────────────────────────┐ │ ┌───────────┐ │ │ │
 │  │┌──────────┐    │   BLOCK   │  │ │ │ ││HEADER    │  │VALIDATOR││ │ │ │ ┌─┴───────────────────────┐ │ │ │SYNC WORKER│ │ │ │
 │  ││DOWNLOADER│    │PROPAGATION│  │ │ │ ││VALIDATOR │  │         ││ │ │ │ │       ETH PEER          │ │ │ │ EXECUTOR  │ │ │ │
 │  │└──────────┘    │  MANAGER  │  │ │ │ │└──────────┘  └─────────┘│ │ │ │ │┌──────────┐   ┌────────┐│ │ │ └───────────┘ │ │ │
 │  │                └───────────┘  │ │ │ │┌──────────┐  ┌─────────┐│ │ │ │ ││WIRE      │   │REQUEST ││ │ │               │ │ │
 │  └───────────────────────────────┘ │ │ ││ BLOCK    │  │BLOCK    ││ │ │ │ ││CONNECTION│   │MANAGER ││ │ │ ┌───────────┐ │ │ │
 │  ┌───────────────────────────────┐ │ │ ││ IMPORTER │  │PROCESSOR││ │ │ │ │└──────────┘   └────────┘│ │ │ │ TX WORKER │ │ │ │
 │  │     TX POOL                   │ │ │ │└──────────┘  └─────────┘│ │ │ │ │┌──────────┐   ┌────────┐│ │ │ │ EXECUTOR  │ │ │ │
 │  │ ┌───────────┐  ┌─────────┐    │ │ │ └─────────────────────────┘ │ │ │ ││PEER      │   │ CHAIN  ││ │ │ └───────────┘ │ │ │
 │  │ │PENDING TXs│  │TX SENDER│    │ │ └─────────────────────────────┘ │ │ ││REPUTATION│   │ STATE  ││ │ │               │ │ │
 │  │ └───────────┘  └─────────┘    │ │                                 │ │ │└──────────┘   └────────┘├─┘ │ ┌───────────┐ │ │ │
 │  └───────────────────────────────┘ │                                 │ │ └─────────────────────────┘   │ │ SCHEDULED │ │ │ │
 │                                    │                                 │ │ ┌─────────────────────────┐   │ │ EXECUTOR  │ │ │ │
 │  ┌───────────────────────────────┐ │                                 │ │ │   ETH MESSAGES          │   │ └───────────┘ │ │ │
 │  │       MINER                   │ │                                 │ │ └─────────────────────────┘   └───────────────┘ │ │
 │  └───────────────────────────────┘ │                                 │ └─────────────────────────────────────────────────┘ │
 └────────────────────────────────────┘                                 │   ┌─────────────────────────────────────────────┐   │
  ┌────────────────────────────────────────────────────────────────┐    │   │          WIRE P2P NETWORK                   │   │
  │                             ºSTATEº                            │    │   └─────────────────────────────────────────────┘   │
  │                   ┌─────────┐    ┌────────────┐                │    │   ┌─────────────────────────────────────────────┐   │
  │                   │WORLD    │    │BLOCKCHAIN  │                │    │   │          DISCOVERY AGENT                    │   │
  │                   │STATE    │    └────────────┘                │    │   └──^──────────────────────────────────────────┘   │
  │                   │ARCHIVE  │                                  │    │      │                                              │
  │                   └─────────┘                                  │    └──────│──────────────────────────────────────────────┘
  │                   ┌─────────┐    ┌────────────┐                │           │ 
  │                   │CONSENSUS│    │ SYNC STATE │                │      DEVp2p Peer Discovery
  │                   └─────────┘    └────────────┘                │      . UDP based system to discover other nodes
  └────────────────────────────────────────────────────────────────┘      . Based on a ºwell-known set of boot nodesº.
                                                                                . Recursively looks up new peers (neighbors) 
pantheon/                                                                         from known peers.
   ├──   bin  (install)                                                         
   ├──   lib  (install)                                                         DISCOVERY PACKET EXCHANGE 
   ├── * key  (run─time) Node Private key (config through --data-path)          - Learns of a node IP:
   └── * ddbb (run─time) RocksDB data     (config through --data-path)            Initiating Node  → Responding Node: Ping
                                                                                  Initiating Node  ← Responding Node: Pong  
  $ bin\besu --config=my.cfg \                                                  
    --data-path=/var/lib/besu/node1 \                                           - What other nodes do you know about?    
    --genesis=my.genesis \                                                        Initiating Node  → Responding Node: Find Neighbors
    --max-peers=5 \                                                               Initiating Node  ← Responding Node: List of known nodes
    --rpc-enabled

LOGS go to STDOUT
Understanding codebase
StartUp:
Initial bootstrap           →  Create BesuController.java             → Create Runner.java
^^^^^^^^^^^^^^^^^              It will collect all bck-related
Parse cli flags                config and services:                         RUnner (BUild through RUnnerBUilder.java):  
(^@cli/BesuCommand.java)       - chain+world state DBs                      (Run through command Line)
parse config file,               - StorageProvider: (InMemory/RocksDB)        - COntains services for:
load|genrate node keypair,     - Genesis Config File                            - Network                    
parse genesis file             - Node keypair                                   - Besu COntroller                                     
                               - ProtocolSchedule + ProtocolSPec:               - JSON RPC                                            
                                                    ^^^^^^^^^^^^                - WebSocket RPC                                       
                                 valid for a "bunch of blocks" in the           - Plugable Metrics System (Prometheus)                
                                 chain (validators and proccessor that          - Data directory                                      
                                 apply to Byzantium,Constantinople, ...).                                                             
                                 The ProtocolSchedule "groups them all"                                                               
                                (@ethereum/mainnet/ProtocolSpec.java)                                                                 
                                 Maps milestone block ranges to                                                                       
                                 specific protocol logic
                               - Synchronizer
                               - Transaction Pool
                               - Miner




Runner: Network Startup:
→ Discover neighbors  →  Setup connections                      
                         DEVp2p Wire Protocol (RLPx)          
                         . Manages which peer nodes are valid
                           (capabilites) and best to talk to
                           (Peer reputation)
                         . Peer Authentication
                         . Encryption (ECIES based on
                           node private keys)
                         . COmpression
                         . Keep Alive

                         DEVp2p Subprotocol
                         - Pluggable subprotocols that handle
                          specific consensys mechanisms such 
                          as Eth, Ibft, Istanbul64Protocol         
                         -ºDefines the set, and appropiateº
                          ºordering of messages on the    º
                          ºnetwork                        º
                         -BºPROTOCOL MANAGERº
                           "Acumulates the logic of different
                            subprotocols"
                           a) Processes incoming messages
                              for their subprotocol
                           b) Sends outbound messages to
                              other nodes using this 
                              subprotocol
                         
                         Example Sample Message Set for EthPV62:
                         - STATUS
                         - NEW_BLOCK_HASHES
                         - TRANSACTIONS
                         - GET_BLOCK_HEADERS
                         - BLOCK_HEADERS
                         - GET_BLOCK_BODIES
                         - BLOCK_BODIES
                         - NEW_BLOCK


ºSYNCHRONIZERº
- Manages the overall sync runtime
-ºChainDownloaderºLoops over:
  - Find best peer to sync from (most/best new data)
  - Pull checkpoint headers (Multithreaded downloading)
  -ºPipelinedºblocks Import
    -ºDownload and validateºheaders
    -ºDownload bodiesº
    - Extract transaction senders (PKI key recovery)
    -ºValidate / Persistºblocks
  -"repeat"

- Github repo:
@[https://github.com/hyperledger/besu]


- Video explaining the general architecture (a "MUST TO" read):
@[https://www.youtube.com/watch?v=OJfib9kTK7U]

- Gitter channel:
@[https://gitter.im/PegaSysEng/pantheon]

Startup Sequence
1.- Parse Command Line
@[https://github.com/hyperledger/besu/blob/master/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java]

2.- Parse Config File

3.- Load or Generate Node Keypair

4.- Parse Genesis File

5.- Create PantheonController
 @[https://github.com/hyperledger/besu/blob/master/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java]
   - Collect all the blockchain-related config and services
   - Chain and world state DBs
     - StorageProvider: Currently supports in-memory and RocksDB
   - Genesis config file
   - Node Keypair
   - ProtocolSchedule and ProtocolSpec: Maps milestone block ranges to specific protocol logic
     Ej: https://github.com/hyperledger/besu/blob/master/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
   - Synchronizer
   - Transaction Pool
   - Miner

6.- Create Runner.java with the help or RunnerBuilder.java:
    Runner.java containser services for:
    - Network
    - Pantheon Controller
    - JSON RPC
    - WebSocket RPC
    - Metrics System (Prometheus)
    - Data directory

7.- Run the Runner instance!


Dev P2P
-ºPeer Discoveryº
  - UDP based system
  - Based on a well-known set of boot nodes.
  - Recursively looks up new peers (neighbors) from known peers

                 DISCOVERY PACKET EXCHANGE

  Initiating Node                                   Responding Node

  Learns of a node IP              Ping →
                                 ← Pong

  What other noedes do you know   Find Neighbors →  Receives Find Neighbors and
  about?                        ← Neighbors         responds with the list of
                                                    known nodes.
-ºWire Protocol (RLPx)º
  - Manages which peer nodes are valid
    and best to talk to (Peer Reputation)
  - Client Capabilities
  - Peer Authentication
  - Encryption (ECIES based on node private keys)
  - Compression
  - Keep Alive

-ºETH Peerº
  Pluggable subprotocols that handle specific consensys mechanisms such as Eth, Ibft, Istanbul64protocol
  - Defines the set, and appropiate ordering of messges on the network
  - Protocol Manager
    a: Processes incoming message sfor this subprotocol
    b: Sends outbound messages to other nodes using this subprotocol.

  Sample message set for EthPV62
  - STATUS
  - NEW_BLOCK_HASHES
  - TRANSACTIONS
  - GET_BLOCK_HEADERS
  - BLOCK_HEADERS
  - GET_BLOCK_BLODIES
  - BLOCK_BODIES
  - NEW_BLOCK

-ºSyncrhonizerº
  - Syncrhonizer
    - Manages the overall sync runtime
  - ChainDownloader Loops over:
    - Find best peer to sync from (most/bes new data)
    - Pull checkpoint header (Multithreaded downloading)
    - Pipelined blocks Import
      - Download and validate headers
      - Download bodies
      - Extract transaction senders (PKI key recovery)
      - Validate and Persist blocks
    - "repeat"
CLI Summary
 ºbesu  blocks importº  imports blocks from file into database.
 ºbesu  blocks exportº  exports a specific block, or list of blocks into file
   
 ºbesu  public-key exportº          print node public key         to STDOUT
 ºbesu  public-key export-addressº  print node public key address to STDOUT
 
 ºbesu  password hashº generate hash of a given password
 
 ºbesu  retesteth º 
  - Run a Retesteth compatible server for º(re)ference (test)sº
  - Usage: besu retesteth
    - Options:
      --data-path=$PATH # RºWARNº Defaults to $BUILD_DIR/besu-$BESU_VERSION
      --rpc-http-host=$HOST
      --rpc-http-port=$PORT
      -l=$LOG VERBOSITY LEVEL
      --host-whitelist=$hostname1,$hostname2,.. or */all
      --logging=$LOG VERBOSITY LEVEL  
 
 ºbesu  rlp encodeº  encodes a JSON typed data into an RLP hex string.
 
 ºbesu  operator generate-blockchain-configº generates node keypairs+genesis file
                                             (with RLP encoded IBFT 2.0 extra data).

CLI Options
@[https://docs.pantheon.pegasys.tech/en/stable/Reference/CLI/CLI-Syntax/]
Updated 2019-10-21

NOTE. Alternatives listed by priority:
- cli flag
- environment variable  # Useful in dockerized enviroments
- configuration file.  (--config-file=file_path)

$ besu [OPTIONS] [COMMAND]
  --banned-node-ids=bannedNodeId1,bannedNodeId2,...
  --bootnodes=enode://id@host1:port1,enode://id@host2:port2,...
  --data-path=dir_path
  --discovery-enabled=false  # defaults to true
  --genesis-file=file_path   # --network is enough for public main/test nets.

GraphQL
  --graphql-http-cors-origins="graphQLHttpCorsAllowedOrigins"
  --graphql-http-enabled
  --graphql-http-host="host" # defaults to 127.0.0.1
  --graphql-http-port="port" # defaults to 8547.
Host Whitelist
  --host-whitelist=host1,host2,... or "*"  # allowed host list to JSON-RPC 
                                           # Defaults to 127.0.0.1, recomended.
  --key-value-storage="keyValueStorageName"# Use only if using a storage system  
                                           # provided with a plugin. Default:rocksdb
  --max-peers=N                            # Specifies the maximum P2P connections 
                                           # that can be established. The default is 25.
Metrics
  --metrics-category="Comma separated list"# BIG_QUEUE, BLOCKCHAIN, EXECUTORS, JVM, NETWORK,
                                           # PEERS, PROCESS, ROCKSDB, RPC, SYNCHRONIZER.
  --metrics-enabled=true                   # Defaults to false
                                           # incompatible with --metrics-push-enabled.
                                           # (either push or pull can be enabled)
    More info at: @[https://docs.pantheon.pegasys.tech/en/stable/HowTo/Deploy/Monitoring-Performance/]
  --metrics-host=prometheus_host           # --host-whitelist is respected
  --metrics-port=tcp_port                  # default to 9545
  --metrics-push-enabled=true|false        # incompatible with --metrics-enabled.
                                           # (either push or pull can be enabled)
                                           # --host-whitelist is respected
  --metrics-push-interval=number_of_secs   # default is 15.
  --metrics-push-port=tcp_port             # default to 9001. 
  --metrics-prometheus-job=prometheus_Job

Mining
  --miner-coinbase=valid_coinbase          # applies with --miner-enabled (or miner_start JSON-RPC method)
                                           # ignored by Clique, IBFT 2.0 consensus
  --miner-enabled
  --miner-extra-data="32 bytes hex string" # will be include in extra-data-field of mined block
                                           # default to 0x.
  --min-gas-price=minTransactionGasPrice

NAT traversal
  --nat-method=UPNP                        # UPNP | NONE(default)
                                           # Can NOT be used with Docker image

Public Eth. Net
  --network=                      # mainnet
                                           # ropsten (PoW)
                                           # rinkeby (PoA+Clique)
                                           # goerli  (PoA+Clique)
                                           # dev     (PoW dev with very low difficulty)
                                           # Incompatible with --genesis-file 
  --network-id="P2P net. integer ID"       # overrides default network ID (chain ID@ genesis file)
Node Private Key
  --node-private-key-file=file_path        # Defaults to data directory. If NOT found a key file
                                           # containing the generated private key is created;
                                           #RºWARN: The private key is not encrypted!!!º

  --p2p-enabled=true*|false
  --p2p-host=p2p_listening_host            # default to 127.0.0.1
  --p2p-interface=ip_nterface              # default to 0.0.0.0 (all interfaces).
  --p2p-port=tcp_port                      # default to 30303. 


Account Permissioning
  --permissions-accounts-config-file-enabled=true|false*  # enable file-based account level perm. 
                                                          # enable file-based account level perm. 
  --permissions-accounts-config-file=path  # Default to permissions_config.toml
                                           # Tip  --permissions-accounts-config-file and
                                           #      --permissions-nodes-config-file    can use the same file.
  --permissions-accounts-contract-enabled=true|false*
  --permissions-accounts-contract-address= # contract address for onchain account permissioning.
  --permissions-nodes-contract-address=    # contract address for onchain node permissioning.
  --permissions-nodes-config-file-enabled=true|false
  --permissions-nodes-config-file=file     # Default to ${BESU_DATA_PATH}/permissions_config.toml
  --permissions-nodes-contract-enabled=true|false*

Privacy
  --privacy-enabled=true|false
  --privacy-marker-transaction-signing-key-file=file  # priv.key used to sign Privacy Marker Transactions. 
                                                      # If not set, each TX is signed with a different
                                                      # randomly generated key.
  --privacy-precompiled-address=priv.Precomp.Address  # default to 126
  --privacy-public-key-file=privacyPublicKeyFile      # pub.key of the Orion node.
  --privacy-url=privacyUrl                            # URL on which Orion node is running.

Debug
  --revert-reason-enabled=true|false*                 # Why default to false?
                                                      # Enabling it use a significant amount of memory.
                                                      # Not recommended for public Ethereum networks.
p2p con Limit
  --remote-connections-limit-enabled=true*|false      # TIP: In private networks with a level of trust
                                                      # between peers, disabling it may increase speed 
                                                      # at which nodes can join the network.
                                                      # WARN: Always enable in pub.nets to avoid eclipse attacks
                                                      #       specially when using fast-sync.
  --remote-connections-max-percentage=0  to 100       # Defaults to 60

HTTP APIs
  --rpc-http-api=csv of enabled APIs through HTTP     # --rpc-http-enabled must also be set to take effect
                                                      #  ADMIN, ETH, NET, WEB3, CLIQUE, IBFT, 
                                                      #  PERM, DEBUG, MINER, EEA, PRIV,TXPOOL.
                                                      #  default: ETH, NET, WEB3
                                                      #RºInvestigate what CLIQUE, IBFT, PRIV, TXPOOL, .. meansº
  --rpc-http-authentication-credentials-file=$file
  --rpc-http-authentication-enabled=true|false*
  --rpc-http-cors-origins=csv of URLs or "*"          # Domain URLs must be enclosed in double quotes
                                                      # Needed for Remix and any other browser app
                                                      # Defaults to "none" (browser apps cannot interact with node)
                                                      # To use Bese as MetaMask backend anywhere, set it to "all"/"*"

  --rpc-http-enabled=true|false*
  --rpc-http-host=$host                               # default to 127.0.0.1
  --rpc-http-port=$port                               # default to 8545 
Web Socket APIs
  --rpc-ws-api=csv of enabled APIs through Web Socket # --rpc-ws-enabled must also be set to take effect
                                                      #  ADMIN, ETH, NET, WEB3, CLIQUE, IBFT,
                                                      #  PERM, DEBUG, MINER, EEA, PRIV,TXPOOL.
                                                      #  default: ETH, NET, WEB3
  --rpc-ws-authentication-credentials-file=$file
  --rpc-ws-authentication-enabled=true|false*         # WARN: auth. requires a token passed by header, not
                                                      # currently supported by 'wscat' 
  --rpc-ws-enabled=true|false*
  --rpc-ws-host=$host                               # default to 127.0.0.1
  --rpc-ws-port=$port                               # default to 8546

Gas Limit Conf
  --target-gas-limit=$GAS_LIMIT_INTEGER
    ^^^^^^^^^^^^^^^^
    Specifies the block gas limit toward which Besu will gradually move on an existing network, 
   ºif enough miners are in agreement.º Use it to change the block gas limit set in the
    genesis fileºwithout creating a new networkº.
   ºThe gas limit between blocks can change only 1/1024thº, so this option tells the 
    block creator how to set the gas limit in its block:
    - If the values are the same or within 1/1024th, the limit is set to the specified value. 
    - Otherwise, the limit moves as far as it can within that constraint.
    - If not specified, block gas limit remains at the value specified in the genesis file.


Pending TX pool
  --tx-pool-max-size=integer                        # Max TX num.kept in pending TX pool. Default to 4096.
  --tx-pool-retention-hours=integer                 # Max hours to retain pending TX in TX pool. Default to 13h.
     
Logging
  --logging=OFF|FATAL|ERROR|WARN|INFO*|DEBUG|TRACE|ALL

Fast sync
  --sync-mode=FAST|FULL*
  WARN: FAST mode, most historical world state data is unavailable.
        Any methods attempting to access unavailable world state data return null.
  --fast-sync-min-peers=integer                     # Minimum peer number before start fast-sync. Default is 5.
  

DevOps
IBFT 2.0 bootstrap
ºPRE-SETUPº
  Download from @[https://github.com/hyperledger/besu/releases]
  $ export BESU_VERSION='1.3.2'
  $ git clone --depth=1 -b '${BESU_VERSION}' --single-branch https://github.com/hyperledger/besu
  $ ./gradlew build -x test  # Build with gradlew wrapper, omit test
  $ cd build/distributions/
  $ tar -xzf besu-${BESU_VERSION}.tar.gz
  $ cd besu-${BESU_VERSION}/
  $ bin/besu --help   # test compilartion is "OK"

  - Linux: In MainNet and "large"nets increase max.number of open files allowed 
    $ sudo ulimit ... RºTODOº
    If the ulimit is not high enough, a 
    º"Too many open files RocksDB exception"º occurs.

@[https://docs.pantheon.pegasys.tech/en/stable/Tutorials/Private-Network/Create-IBFT-Network/]

ºSTEP 01: BOOTSTRAP NODE CONFIGURATION:º
 INPUT                   BOOTSTRAP SCRIPT                                  OUTPUT (INPUT TO NODE CONFIG)
 
 ºibftConfigFile.jsonº  →  $ besu operator generate-blockchain-config \ →  ./networkFiles/
  ^^^^^^^^^^^^^^^^^^^   º--config-file=ibftConfigFile.jsonº\               ├Bºgenesis.jsonº
  |                      --to=networkFiles --private-key-file-name=key     └  keys
  {                                                                           ├Bº0x--20 bytes pub.address 01º--
  º"genesis":º{                                                               │  ├─ key
     "config": {                                                              │  └─ key.pub
        "chainId": 2018,                                                      ├Bº0x--20 bytes pub.address 02º--
        "constantinoplefixblock": 0,                                          │  ├─ key
        "ibft2": {                                                            │  └─ key.pub
          "blockperiodseconds": 2,                                            ├Bº0x--20 bytes pub.address 03º--
          "epochlength": 30000,                                               │  ├─ key
          "requesttimeoutseconds": 10                                         │  └─ key.pub
        }                                                                     └Bº0x--20 bytes pub.address 04º--
      },                                                                         ├─ key
      "nonce": "0x0",                                                            └─ key.pub
      "timestamp": "0x58ee40ba",
      "gasLimit": "0x47b760",
      "difficulty": "0x1",
      "mixHash": "0x-- 32 bytes Gº*1º--",
      "coinbase": "0x00...20bytes..00",
      "alloc": {
         "fe3b...20 bytes...bd73": {
            "balance": "0xad78ebc5ac6200000"
         },
         "6273...20 bytes...Ef57": {
           "balance": "90000000000000000000000"
         },
         "f17f...20 bytes...b732": {
           "balance": "90000000000000000000000"
         }
        },
      "extraData": "0x....", ← rlp encoded:
   },                          - @[https://github.com/ethereum/wiki/wiki/RLP]
                               - @[https://besu.hyperledger.org/en/stable/Reference/CLI/CLI-Subcommands/#rlp]
  º"blockchain":º{
     "nodes": {
       "generate": true,
         "count": 4         ←──── number of node key pairs to be generate
     }                            4+ validators needed in IBFT 2.0 to really 
   }                              be BFT
  }
 Gº*1º:0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365

ºSTEP 02: SETUP NODE CONFIG LAYOUT Copying Bootstrap output from STEP 01º
IBFT-Network/
├──Bºgenesis.jsonº  (output from bootstrap)
├── Node-1
│   ├─ data
│   │  ├── key     (output from ./Bº0x--20 bytes pub.address 01º/key--)
│   │  ├── key.pub (output from ./Bº0x--20 bytes pub.address 01º/key.pub--)
├── Node-2
│   ├─ data
│   │  ├── key     (output from ./Bº0x--20 bytes pub.address 02º/key--)
│   │  ├── key.pub (output from ./Bº0x--20 bytes pub.address 02º/key.pub--)
├── Node-3
│   ├─ data
│   │  ├── key     (output from ./Bº0x--20 bytes pub.address 03º/key--)
│   │  ├── key.pub (output from ./Bº0x--20 bytes pub.address 03º/key.pub--)
└── Node-4    
    ├─ data
    │  ├── key     (output from ./Bº0x--20 bytes pub.address 04º/key--)
    │  ├── key.pub (output from ./Bº0x--20 bytes pub.address 04º/key.pub--)


 
ºSTEP 03: Start the Networkº
 $ export COMMON=""
 $ export COMMON="$COMMON --data-path=data"
 $ export COMMON="$COMMON --genesis-file=../genesis.json"
 $ export COMMON="$COMMON --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT"
 $ export COMMON="$COMMON --host-whitelist='*' --rpc-http-cors-origins='all'"
  
 $ cd .../Node-1
 $ besu $COMMON 
 --- Copy enode URL to specify Node-1 as the bootnode for the other nodes --
 
 $ cd .../Node-2
 $ besu $COMMON --bootnodes=$ENODE1_URL --p2p-port=30304 --rpc-http-port=8546
 
 $ cd .../Node-3
 $ besu $COMMON --bootnodes=$ENODE1_URL --p2p-port=30305 --rpc-http-port=8547
 
 $ cd .../Node-4
 $ besu $COMMON --bootnodes=$ENODE1_URL --p2p-port=30306 --rpc-http-port=8548

ºSTEP 04: Confirm Private Network is Workingº

 $ curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}' localhost:8545
 -- Output must confirm 3 peers for node 1
 → {
 →   "jsonrpc" : "2.0",
 →   "id" : 1,
 →   "result" : "0x3"
 → }
 
Look at the logs displayed to confirm blocks are being produced.

Add/Remove validators
- Use the IBFT API to remove or add validators.
  @[https://docs.pantheon.pegasys.tech/en/stable/Reference/API-Methods/#ibft-20-methods]

PRE-SETUP: Enable IBFT API in --rpc-http-api and/or --rpc-ws-api

API:
 ºibft_discardValidatorVoteº
  - Discards a proposal to add or remove a validator with the specified address.
  - Parameters
    data - 20-byte address of proposed validator
  - Returns
    result: boolean - true
  - Example
    METHOD="ibft_discardValidatorVote"
    PARAMS='["0xef1bfb6a12794615c9b0b5a21e6741f01e570185"]'
    URL=http://127.0.0.1:8545
    curl -X POST --data '{"jsonrpc":"2.0","method":"$METHOD","params":$PARAMS, "id":1}' $URL

 ºibft_getPendingVotesº
  - Returns current votes.
  - No Parameters
  - Returns
    json Map of account addresses to corresponding boolean values indicating the vote for each account.
    - If true, the vote is to add a validator. 
    - If false, the proposal is to remove a validator.
  - Example
    METHOD="ibft_getPendingVotes"
    curl -X POST --data '{"jsonrpc":"2.0","method":"$METHOD","params":[], "id":1}' $URL 

 ºibft_getValidatorsByBlockHashº
  - Lists validators defined in the specified block.
  - Parameters
    - data - 32-byte block hash
  - Returns
    - result: array of data - List of validator addresses
    METHOD="ibft_getValidatorsByBlockHash"
    PARAMS='["0xbae7d3feafd743343b9a4c578cab5e5d65eb735f6855fb845c00cab356331256"]'
    curl -X POST --data '{"jsonrpc":"2.0","method":"$METHOD","params":$PARAMS, "id":1}' $URL 

 ºibft_getValidatorsByBlockNumberº
  - Lists the validators defined in the specified block.
  - Parameters
    quantity|tag - block number int  OR
                   one of the string tags latest, earliest, or pending
  - Returns
    - result: array of data - List of validator addresses
    METHOD="ibft_getValidatorsByBlockNumber"
    PARAMS='["latest"]'
    curl -X POST --data '{"jsonrpc":"2.0","method":"$METHOD","params":$PARAMS, "id":1}' $URL 

 ºibft_proposeValidatorVoteº
  - Proposes adding or removing a validator with the specified address.
  - Parameters
    data - Account address
    boolean - true to propose adding validator or false to propose removing validator.
  - Returns
    result: boolean - true
  - Example
    METHOD="ibft_proposeValidatorVote"
    PARAMS='["42d4287eac8078828cf5f3486cfe601a275a49a5",true]'
    curl -X POST --data '{"jsonrpc":"2.0","method":"$METHOD","params":$PARAMS, "id":1}' $URL

 ºbft_getSignerMetricsº
  - Provides validator metrics for the specified range:
    Number of blocks from each validator
    Block number of the last block proposed by each validator (if any proposed in the specified range)
    All validators present in the last block of the range
  - Parameters
    - fromBlockNumber: int or 'earliest' 
    - toBlockNumber  : int or 'latest' , 'pending' 
    ^^^^^^^^^^^^^^^^^
    If from/to NOT specified, last 100 blocks are used.
    If      to NOT specified, defaults to 'latest'
  - Returns:
    result: JSON List of validator objects
            Note: genesis block proposer has address 0x0000000000000000000000000000000000000000.
  - Example
    METHOD="ibft_getSignerMetrics"
    PARAMS='["1", "100"]'
    curl -X POST --data '{"jsonrpc":"2.0","method":"$METHOD","params":$PARAMS, "id":1}' $URL


Accounts for testing (--network=dev) @[https://docs.pantheon.pegasys.tech/en/stable/Reference/Accounts-for-Testing/] ºAlternative 1:º - use nextºpredefined accountsºin dev network (--network=dev) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ dev.json genesis file will be used ºAccount 1 (Miner Coinbase Account)º Address: 0xfe3b557e8fb62b89f4916b721be55ceb828dbd73 Private key : 0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63 Initial balance : 0xad78ebc5ac6200000 (200000000000000000000 in decimal) ºAccount 2º Address: 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 Private key : 0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 Initial balance : 0x90000000000000000000000 (2785365088392105618523029504 in decimal) ºAccount 3º Address: 0xf17f52151EbEF6C7334FAD080c5704D77216b732 Private key : 0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f Initial balance : 0x90000000000000000000000 (2785365088392105618523029504 in decimal ºAlternative 2:º - reuse existing test accounts by editing the genesis file (--genesis-file) Infrastructure: Disk/RAM DISK Space: RAM: test/private network -200+MB - 4+GB RAM mainnet/public-test-net -1.5+TB - 8+GB RAM Notes: 2019-01 Testing with pantheon-quick-start and IBFT 2.0 with defaults settings (1 block each 5? seconds) the disk compsumption is: 1 hour 1 day 1year 2044K 47.9MB 17485.8MB IBFT2 Consensus Case: - Each mined block has a minimum length of 648 bytes for empty blocks. - With a block-period configured to 5 seconds, this leads to: print( ( 648 / (1024.*1024.) ) * 12 * 60 * 24) ~ º10.68 MBytes/dayº ^^^^^^^^^^^^^^^^^^ ^ ^ ^ ^^^^^^^^^^^^^^^^ block-size in MBytes blks/min mins/hour hours/day Minimum ussage. 5secs/blk Just empty blocks. No indexes, external logs, file-system metadata, ...
Monit running network (Prometh.+Grafana) Extracted from @[https://gitter.im/PegaSysEng/pantheon] on 2019-05-29 20:01 Adrian Sutton@ajsutton We've just published a Grafana dashboard as an example for monitoring Pantheon nodes: ºwhether they're in syncº, number of peers, cpu and memory usage etc. It'sºavailable at:º @[https://grafana.com/dashboards/10273] and instructions for setting up Pantheon and Prometheus is at @[https://pantheon.readthedocs.io/en/stable/Using-Pantheon/Monitoring/#setting-up-and-running-prometheus-with-pantheon] ... I did sneak some extra metrics into trunk yesterday so the board work best with a build from master or anything from 1.1.2 onwards once it's released. backup, disaster recovery
  Minimum Private network
@[https://docs.pantheon.pegasys.tech/en/stable/Getting-Started/Run-Docker-Image/]
@[https://docs.pantheon.pegasys.tech/en/stable/Tutorials/Create-Private-Network/]        (PoW)
@[https://docs.pantheon.pegasys.tech/en/stable/Tutorials/Create-Private-Clique-Network/] (PoA Clique)
@[https://docs.pantheon.pegasys.tech/en/stable/Tutorials/Create-IBFT-Network/]           (PoA IBFT)
$ git clone --branch 1.1.0 @[https://github.com/PegaSysEng/besu-quickstart]
$ cd pantheon-quickstart
$ ./run.sh               ← build docker images and run the containers
                           It also scales the regular node container to four containers
                           to simulate a network with enough peers to synchronize.

   (ouput will be similar to)
   → List endpoints and services
   → ----------------------------------
   →         Name                       Command               State                              Ports
   → -----------------------------------------------------------------------------------------------------------------------------
   → quickstart_ºbootnodeº_1    /opt/pantheon/bootnode_sta ...   Up      30303/tcp, 8545/tcp, 8546/tcp
   → quickstart_ºexplorerº_1    nginx -g daemon off;             Up      0.0.0.0:32770 →80/tcp
   → quickstart_ºminernodeº_1   /opt/pantheon/node_start.s ...   Up      30303/tcp, 8545/tcp, 8546/tcp
   → quickstart_node_1          /opt/pantheon/node_start.s ...   Up      30303/tcp, 8545/tcp, 8546/tcp
   → quickstart_node_2          /opt/pantheon/node_start.s ...   Up      30303/tcp, 8545/tcp, 8546/tcp
   → quickstart_node_3          /opt/pantheon/node_start.s ...   Up      30303/tcp, 8545/tcp, 8546/tcp
   → quickstart_node_4          /opt/pantheon/node_start.s ...   Up      30303/tcp, 8545/tcp, 8546/tcp
   → quickstart_ºrpcnodeº_1     /opt/pantheon/node_start.s ...   Up      30303/tcp, 0.0.0.0:32769→8545/tcp, 0.0.0.0:32768→8546/tcp
   → ...
   → JSON-RPC HTTP service endpoint      :ºhttp://localhost:32770/jsonrpcº
   → JSON-RPC WebSocket service endpoint :ºws://localhost:32770/jsonws   º
   → Web block explorer address          :ºhttp://localhost:32770        º
   →

$ ./list.sh  ← (re)display list of endpoints again

...
$ ./stop.sh  ← shut down private network without deleting the containers
               (./start.sh to restart)

$ ./remove.sh ← Shut downa and remove all data.

  set max Contract size
- Done at the network (genesis.json) config level.
@[https://docs.pantheon.pegasys.tech/en/stable/Configuring-Pantheon/Config-Items/]
 Network             configuration items are specified in the genesis file.
 Item                Description
 Chain ID            Chain ID for the network
 Milestone blocks    Milestone blocks for the network
 ethash              Specifies network uses Ethash and contains fixeddifficulty
 clique              Specifies network uses Clique and contains Clique configuration items
 ibft2               Specifies network uses IBFT 2.0 and contains IBFT 2.0 configuration items
ºcontractSizeLimitº  ← free gas networks. Default is 24576 and the maximum size is 2147483647.
ºevmStackSize     º  Maximum stack size. Specify to increase the maximum stack size in
                     private networks with very complex smart contracts. Default is 1024.
What's New
1.4
@[https://pegasys.tech/introducing-plugin-apis-in-hyperledger-besu/]
@[https://jira.hyperledger.org/browse/BESU-91?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel]

Plugin API allows to fetch data from running Besu node:

BESU node → (data) → (Besu 1.4+) → feed to DDBBs, kafka, ...
            ^^^^^^    Plugin-API
          - Blocks
          - Balances
          - Transactions
          - Smart Contracts
          - Execution Results
          - Logs 
          - Syncing State

- In the future, along with more data being exposed via the API, users can expect 
  Besu to compartmentalize key supporting services, eventually allowing them to 
  be swapped via a plugin.
  Ex: PegaSys Plus 1st release, made DDBB swappable to support encryption at rest. 
1.2 Release
2019-08
- additional improvements to our privacy groups
@[https://docs.pantheon.pegasys.tech/en/latest/Privacy/Explanation/Privacy-Overview/?]

- Better Security:
  - Permissioning User Interface:
    - Manage nodes and accounts with a new dAPP designed to make whitelisting easy to read and edit.
    @[http://docs.pantheon.pegasys.tech/en/stable/Permissions/Onchain-Permissioning/Onchain-Permissioning/]
    @[https://youtu.be/lwaZ4JhLhH0]

  - Account-level Permissioning
    Limit transactions to trusted/known Ethereum accounts on your network.

- Improved Privacy Groups:
  - Multiple ºprivacy groupsº with same membership can exist and be used for different purposes.
  - Names and description metadata can be embedded in privacy groups on-chain for clarity.

  - EthSigner for External Key Management
    - now compatible with Hashicorp KeyVault and Azure Key Vault):
    - Solve security issues created by storing key management mechanisms within the Ethereum Client. External key management through cloud or private stores.
    @[https://docs.ethsigner.pegasys.tech/en/latest/]

- New Integrations and Upgrades
  - New GraphQL Interface:
    - Execute a whole set of common queries against Pantheon easier;
    - visualize and adjust queries.
    @[https://docs.pantheon.pegasys.tech/en/stable/Pantheon-API/GraphQL/]

  - Simplified Network Configuration:
    Automatically configure ºUPnP routersº to allow inbound connections
    for easier network configuration.
Non Classified
Gemalto HSM
@[https://safenet.gemalto.com/data-encryption/hardware-security-modules-hsms/protectserver-security-module/]
- Supports SECP256K1 , required by Ethereum
"npm-solc"
ALT 1:
$ sudo npm install -g solc

*probably the most portable and most convenient way to install
Solidity locally*
 A platform-independent JavaScript library is provided by
compiling the C++ source into JavaScript using Emscripten for
browser-solidity and there is also an npm package available.

Alt 2:
Ubuntu PPAs.
Solidity Documentation, Release 0.4.8-develop
$ sudo add-apt-repository ppa:ethereum/ethereum
                          ^^^^^^^^^^^^^^^^^^^^^
                          For cutting-edge add also also
                          ppa:ethereum/ethereum-dev
$ sudo apt-get update
$ sudo apt-get install solc
Azure 
offline signing
https://tomislav.tech/2018-02-05-ethereum-keyvault-signing-transactions/
ethereumjs-vm
@[https://github.com/ethereumjs/ethereumjs-vm]
EthVM
EthVM is an open-source Blockchain Explorer focused mainly on Ethereum
(although other networks and forks will be supported over time)
under the SSPL license (a small variation of the GNU Affero License v3)
and written in a mixture of different languages.

Our core infrastructure is based on well known languages:
    TypeScript
    Kotlin

And also is backed by popular frameworks:
    Apache Kafka = Kafka Connect + Kafka Streams + Kafka Schema Registry
    VueJs
    NestJS

Example ussage of Kafka streams as "micro-esb" to transform Etherum events:
https://github.com/EthVM/EthVM/tree/develop/apps/processing/kafka-streams/src/main/kotlin/com/ethvm/kafka/streams
ethereumj
@[https://github.com/ethereum/ethereumj]
EVM trick
http://martin.swende.se/blog/EVM-Assembly-trick.html#
"""I recently discovered a method to do generic proxying of Ethereum calls.
Skip further down for nitty gritty details, I’ll start this off with some
basics.
The problem
Sometimes, it’s convenient to build contract factories. For example, say you
want to implement crowdsourcing, or auctions, or games, or DAOs. In those
cases, instead of having one “Mother” auction which keeps track of active
auctions (which, in turn keep track of bidders, offers and items), it makes
sense to implement each auction/crowdfund/game/DAO as it’s own contract.

One problem is that these contracts are quite heavy; creating them may be
very expensive and the creation of several may be limited by block gas limits
. To counter this, the library-model can be used instead:
"""

Solidity
Security
Considerations
@[http://solidity.readthedocs.io/en/develop/security-considerations.html#security-considerations]
Ethereum
Package
Registry

@[https://www.ethpm.com/]
- A package index for Ethereum smart contract packages.

The Ethereum Package Registry is a package index for Ethereum smart contract
packages. The registry is based on the ERC190 Smart Contract Packaging
Specification.

"""Dear Ethereum,
We need to talk. You're not the easiest platform to work with. Don't get me
wrong, you have some great qualities but it's time to grow up and start
acting a bit more... mature

Since we care about you and really want you to succeed we made you something
that should help. It's called a package index.

I know change can be a little scary but we're sure that once you try it you'
ll love it. Developers are going to like you more. Their bosses may even stop
seeing you as the dangerous kid teaching their devs bad habits like copy/pasting code.
Please give it a try. We really do want the best for you.
Serverless Mist
@[https://blog.ethereum.org/2016/07/12/build-server-less-applications-mist/]
- How to build server less applications for Mist
azure
workbench

https://docs.microsoft.com/en-us/azure/blockchain/workbench/
https://github.com/azure-samples/blockchain-devkit
https://docs.microsoft.com/en-us/azure/blockchain/workbench/deploy#deploy-blockchain-workbench
Microsoft Azure Blockchain Workbench
This repository contains content and samples in number of areas, including:
- Connect      : Connect various data producers and consumers to or from the blockchain
- Integrate    : Integrate legacy tools, systems and protocols
- Accelerators : Deep dive into End-to-End examples, or solutions to common patterns.
- DevOps for   : Bring traditional DevOps practices into a distributed application environment
  smart contracts
(Openshift)Strato
@[https://github.com/blockapps/strato-getting-started]
@[https://github.com://github.com/blockapps/strato-openshift]
Buidler
@[https://buidler.dev/]
@[https://www.npmjs.com/package/@nomiclabs/buidler-ethers]
...

- Buidler: task runner for Ethereum smart contract developers.

- It works with all developer tools, rather than replace any
  specific ones. It's value comes from being the connective tissue,
  rather than from specific functionality. It's an integration
  platform for other tools to build upon.


Web3-Secret-Storage-Definition
@[https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition]
NuCypher
@[https://www.nucypher.com/]
nuCypher. Privacy Infrastructure for the Decentralized Web

- Alice has sensitive data that she wants to store and share.
- Alice encrypts her data using her public key and uploads it to storage.
- Alice delegates access to Bob. The data is rekeyed to Bob's key using proxy re-encryption
- Bob downloads the data and decrypts it with his own private key.

ºProxy Re-encryption (PRE)º

NuCypher's PRE network provides cryptographic access controls for distributed apps and protocols.

ºFully Homomorphic Encryption (FHE)º
NuCypher's NuFHE library enables secure, private computation on encrypted data by outsourced nodes.

See also:
@[https://blog.nucypher.com/numerology-fast-ecc-arithmetic-on-chain-5eb438a735d4]
SmartCard USB HSM
@[https://blog.coinfabrik.com/using-the-cardcontact-smartcard-usb-hsm-in-an-ethereum-poa-chain/]
Using the CardContact SmartCard USB HSM in an Ethereum PoA Chain
ethpm-js
  https://github.com/ethpm/ethpm-js
      Javascript library for publishing and consuming Ethereum packages,
      provides utilities for publishing and consuming Ethereum packages based
      on the Ethereum Package Manager specification. It is meant to be integrated
      directly into development tools to support their use of the Ethereum Package
      Management ecosystem.

  https://etherscan.io/pushTx
      Send raw-transactions
  tmux: General (BSD/Linux/UNIX) tool for multiplexing terminals and create long-running
      sessions that persists ssh disconnections.
      - It allows for example to have an terminal with vim editing solidity files,
        another one editing JS files, another one with the truffle debugger,
        the geth console, ...
      - Sessions will persists until the PC/server is restarted. We can disconnect
        and reconnect to the same session repeatedly. The terminal layout will be
        saved.
      - It also allow different users to share the session and terminals and is
        very efficient in terms of bandwidth (when compared to VNC or RDesktop),
        since there are not graphics involved.
Tech.Radar
Ethr-DIDs
(uPort++)
@[https://medium.com/uport/goodbye-uport-dids-hello-ethr-dids-ea2e80256f54]
@[https://github.com/uport-project/ethr-did-registry]
- Goodbye uPort DIDs, Hello Ethr-DIDs
  We have released a major app update that enables migrating all old uPort 
  identities created before September 2018, to the current DID architecture. 
  Not to worry though, your old Identity data will still be available to use 
  and all verifications issued will be available
Piet
@[https://blog.slock.it/analyzing-solidity-smart-contracts-with-piet-6db33a733e79]
@[https://github.com/slockit/piet]
@[https://piet.slock.it/?container=examples%2Fexport1562664060589.piet.json]

- parses Solidity code, graphically representing contracts and
 their relations (inheritance structure,...).
- Web GUI to read the state, send transactions, or list events
- create smart contract documentation from NatSpec annotations.
- support for Solidity source files, Truffle build files, piet container files
  and GitHub repositories.
- Can use web3 injected objects ("MetaMask") to interact with a live blockchain.

RºWarning: Piet has not yet undergone in-depth testing and may contain serious bugs.º
Grid
@[https://github.com/ethereum/grid]
Grid is a desktop application that allows you to securely download,
configure and use various clients and tools in the Ethereum ecosystem.
(Geth, Parity, IPFS,...)
Alpha state as 2019-09-08
GNOSIS Research
@[https://github.com/gnosis/research]
Status
Wallet an IM
@[https://status.im/]
@[https://github.com/status-im/status-react]
- currently in alpha:
- can be tested on Android and iPhone.
- Status is a mobile messenger, crypto wallet, and Web3 browser.
- peer-to-peer protocol that doesn't rely on centralized servers.

@[https://ethereum.stackexchange.com/questions/18461/how-can-dapps-work-on-smartphones]
  - Download Status on your phone
  - configure an account
  - Install 
    $ npm i -g status-dev-cli
  - In status console, enter /debug. 
    That will give you your device IP address {DEVICE_IP}
  - From your machine, make sure you can see you device and status:
    status-dev-cli scan (status must be running)
  - Last step, consist in registering the dapp in status:
    status-dev-cli add 
       "{\"whisper-identity\": \"my-dapp\", \"dapp-url\": \"{DAPP_URL}\", \"name\": \"MyDAPP\"}" --ip {DEVICE_IP}
Augur Prediction Markets
@[https://www.augur.net/]
Markets for Anyone Anywhere on Anything
- politics and elections prediction markets
- sport and football prediction markets
- crypto and bitcoin prediction markets
- prediction markets on anything
- ...
Homomorphic Hashing
@[http://blog.notdot.net/2012/08/Damn-Cool-Algorithms-Homomorphic-Hashing]