You can also be interested in the Web Technologies and Cryptography maps.☜
Fund and influence the evolution of this page by sending some milliethers to my Ether Wallet .
About Ethereum
External Links
@[https://github.com/ethereum/wiki/wiki/White-Paper]
@[https://ethereum.github.io/yellowpaper/paper.pdf]
@[https://solidity.readthedocs.io/]
@[https://solidity.readthedocs.io/en/latest/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://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]
 @[https://github.com/ConsenSys/EthOn/]
 @[https://ethon.consensys.net/statistics.html]
- 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.

- Shahan Khatchadourian
  - Pegasys Eng. Co-founder
  - Created Hyperledger Besu

Co-founder@PegaSys

- 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=]
  @[https://medium.com/@loredana.cirstea/dtype-decentralized-type-system-functional-programming-on-ethereum-4f7666377c9f]
  @[https://www.youtube.com/watch?v=GZg4L2o0Nyw&feature=youtu.be]

- 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

- Ronan Sandford (wighawag), prominent smart contract developer:
  - author of ERC-1155 standard
  - working on diamonds standards support in buidler-deploy. 

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

- Rob Hitchens:
@[https://medium.com/@robhitchens]
@[https://about.me/hitchens]
  Distributed Applications Architect and Mentor in Calgary, Alberta, Canada
  Top poster on Ethereum Stack exchange since 2016.
  Co-author and mentor, Ethereum Developer, Hyperledger Fabric
  Developers, Quorum Developer, Hyperledger Sawtooth Lake Developer and
  Tezos Developer training at B9lab.com since 2017.
  Advisor and co-founder, Solidified.io, Ethereum smart contract
  quality assurance.
  - Author of Solidity CRUD:
  @[https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a]

- Nick Mudge: Designed the Diamon Standard (EIP 2535) for proxy-contracts

- Anjan Roy @[https://github.com/itzmeanjan]
  Lead Blockchain Engineer @ Polygon ("Matic Network"). 


- DApps and Solidity Development:
  - Manuel Araoz: @[https://maraoz.com/]:
    CTO&co-founder at Zeppelin.
  - Luis Cuende: @[http://blog.aragon.one/author/luis/]
    CEO and cofounder of Aragon One

  - b9lab: Quality Blockchain Education for everyone
  @[https://www.b9lab.com/]
    - Xavier Lepretre, senior consultant at B9Lab

  - Steve Marx @[https://ethereum.stackexchange.com/users/19510/smarx]
    and Tood Proebsting:
    Authors of @[https://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

- Hudson Jameson (@Souptacular)
@[https://hudsonjameson.com/]

- Nick Savers (@nicksavers)

- Martin Becze (@wanderer)

- Greg Colvin (@gcolvin)

- Alex Beregszaszi (@axic)



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º


- 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)
Network Versions
• Protocol and Code Updates:
@[https://ethereum.github.io/yellowpaper/paper.pdf]
@[https://en.wikipedia.org/wiki/Ethereum#Milestones]
  Name/Code Name     1st Block  Release     Public Ethereum    Network        Notes
                        Number  date        Network Version    Block Reward
  Frontier                   0  2015-07-30 
  ---------------------------------------------------------------------------------
  Ice Age               200000  2015-09-08 
  ---------------------------------------------------------------------------------
  Homestead            1150000  2016-03-15  Homestead          5 ether
  ---------------------------------------------------------------------------------
  DAO Fork             1920000  2016-07-20 
  ---------------------------------------------------------------------------------
  Tangerine Whistle    2463000  2016-10-18 
  ---------------------------------------------------------------------------------
  SpuriousDragon       2675000  2016-11-23 
  ---------------------------------------------------------------------------------
  Byzantium            4370000  2017-10-16  Metropolis Part1*1
  ---------------------------------------------------------------------------------
  Constantinople *4    7280000  2019-02-28  Metropolis Part2*2
  +                                        ----------------------------------------
  Petersburg           7280000  2019-02-28 
  ---------------------------------------------------------------------------------
  Istanbul             9069000  2019-12-08 
  ---------------------------------------------------------------------------------
  MuirGlacier          9200000  2020-01-02 
  ---------------------------------------------------------------------------------
  Berlin              12244000  2021-04-15 
  ---------------------------------------------------------------------------------
  London              12965000  2021-08-05 
  ---------------------------------------------------------------------------------
  ArrowGlacier        13773000
  ---------------------------------------------------------------------------------
                                            Serenity *3 
                                            PoS replacing PoW
 
  *1 Byzantium hardfork == """ Ethereum for the masses """.
   @[https://www.infoq.com/news/2017/08/Ethereum-HardFork]
    - It ºincreases anonymity through Zero-knowledge zk-snark proofsº,
    - It includes more predictable gas charges which were becoming
      difficult to calculate with the increased number of ICOs.
  *2 Metropolis Part 2,Constantinople: (Aka "Ethereum 2.0"):
     - It lays 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º.
        RºDelayed, not yet complete on 2021-12º or 1y9months later.
      - spec freeze: 20??-06-30
        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.
       "...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."""
    

  *3 Serenity: Ethereum 2.0 "last phase", 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 Smart Contracts.
         - 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.

     Due to the advances in (optimistic/zk)+Rollups chains it's quite
     possible that Ethereum 2 ends up being Ethereum 1.5
     (Ethereum 1 + Sharding) + zk-Rollups as explained by Vitalik in:
   @[https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698]
     """
      ...base-layer scaling would primarily be focused on scaling how much 
      data blocks can hold, and not efficiency of on-chain computation or 
      IO operations.ºThe only determinant of the scalability of a rollup is º
     ºhow much data the chain can hold, and any increase beyond the current º
     º~60 kB/sec will help...º
      • Ethereum 1-L1                : ~15 TPS.
      • everyone moving to rollups   : ~3000 TPS.
      • rollups + eth2 sharded-chains:  up to ~100_000 TPS.
      • eth2 + phase2                : ~1000-5000 TPS on L1 
                                        (100x less than Rollups).
                                        ^^^^^^^^^^^^^^^^^^^^^^^^.
       ºIT SEEMS VERY PLAUSIBLE TO ME THAT WHEN PHASE 2 FINALLY COMES,º
       ºESSENTIALLY NO ONE WILL CARE ABOUT IT.º
     """

  *4 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 (Ropsten,...)


  REFs:
  - 2018-06-16: Casper and sharding merger confirmed
  @[https://www.trustnodes.com/2018/06/16/casper-sharding-merger-confirmed-constantinople-back-table]
  - 2019-02-22: scheduled upgrade at block number 7,280,000,  predicted on 2019-02-28
  @[https://blog.ethereum.org/2019/02/22/ethereum-constantinople-st-petersburg-upgrade-announcement/]


Chain IDs running EVMs Smart Contracts • REFs: · @[https://chainid.network/] · @[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids] ·(+ Summary from original project sources) • NOTE:read @[#layer2_scalability_summary] for difference among side-chains and rollups. (TLDR: rollups: safer, side-chains: Easier/more centrilized). ┌─ TheGraph Protocol Support Chain Name/Chain ID │Symb│││ notes ─────────────────────│────│─│───────────────────────────────────────────────────── ethereum | | | └ mainnet/1 | ETH| | └ testnet kovan/42 | KOV| | └ testnet görli/5 | GOR| | └ testnet ropsten/3 | ROP| | └ testnet rinkeby/4 | RIN| | ---------------------|----| |----------------------------------------------------- expanse net/2 | EXP| | ---------------------|----| |----------------------------------------------------- thaichain/7 | TCH| | thaishield audits verify your └ 2.0 thaifi/17 | TFI| | distributed systems work as intended. | | | our engineers fully review system’s | | | architecture and codebase, and then | | | write a thorough report with | | | actionable feedback for every issue. --------------------------| |----------------------------------------------------- ubiq/8 | UBQ| | built upon improved version of e.codebase, └ testnet/9 | | | it offers enterprise-stable pow. | | | conservative upgrade schedule. --------------------------|-|----------------------------------------------------- arbitrum one/42161 |AETH|Y| optimistic rollup. └ test.rinkeby/421611|aRETH | integrated with binance exchange | | | (but withdrawals not yet enabled | | | as of 2021-11-26 ) └ on xdai/200 |XDAI| | (research project) --------------------------|-|----------------------------------------------------- Optimistic Eth./10 |OETH|Y| type: l2 optimistic-rollup └ testnet kova/69 | KOR| | millisec tx,10-100x cheaper. └ testnet goerly/420 | GOR| | periodically submit l2 tx merkle root to | | | mainnet, storing N L2 tx 1 tx mainnet. | | | https://chainid.lin/?network=optimism | | | node: https://mainnet.optimism.io | | | expl: https://optimistic.etherscan.io | | | supported by infura. ---------------------|----|-|----------------------------------------------------- xDAI Chain/100 |xDAI|Y| Aims at creating Stable Payments Fees tied to USD ---------------------|----|-|----------------------------------------------------- NEAR/??? |????|Y| It runs in concert with Ether/Polka./Cosmos/ | | | ---------------------|----|-|----------------------------------------------------- CELO/??? |????|Y|• https://celo.org | | |• PoS, mobile-1st platform for fin.dApps+crypto payments | | |• KickStart anounced that its platform will change to | | | be based on the Celo blockchain in 2021-12. | | |• CELO founders/inverstors include Jack Dorsey (Twitter | | | CEO), SocialCapital, CoinBase, Telekom, ... ---------------------|----|-|----------------------------------------------------- AVALANCHE/??? |????|Y| ---------------------|----|-|----------------------------------------------------- POA/??? |????|Y| ---------------------|----|-|----------------------------------------------------- MOONRIVER/??? |????|Y| ---------------------|----|-|----------------------------------------------------- Fuse Mainnet/122 |FUSE|Y| "Open Source" Economy, create Branded wallets... └ Sparknet/123 SPARK| | 47 validators, ... ---------------------|----|-|----------------------------------------------------- polygon Main./137 MATIC|Y| type: side-chain, (rollup too? ) └ Test.Mumbai/80001 MATIC| | https://polygon.technology/ | | | polygon: protocol+framework to build+ | | | connect Ether. compatible Networks ---------------------|----|-|----------------------------------------------------- palm Main./*1 |PALM| | sidechain for selling⅋trading └ Testnet/*2 |PALM| | real-world and digi. assets NFTs. *1:11297108109 | | | IBFT 2.0 poa consensus. *2:11297108099 | | | (pseudo-centralized/consortium net). | | | automated mainnet bridge relay service. | | | Connect payment tokens (DAI, NFTs) with | | | bridging contracts deployed on both | | | networks. Fees collected from this | | | bridge are partially used to purchase | | | carbon offsets. ---------------------+----|-|----------------------------------------------------- Metadium Main./11 |META| | Self Sov. Identity with 2 Factor Authentication └ Testnet/12 | KAL| | ---------------------|----| |----------------------------------------------------- GoodData Main./32 |GooD| | NFTs/"Metaverse" └ Testnet/33 |GooD| | AI and ML Optimize Rewards | | | Region-aware distributed storage ---------------------|----| |----------------------------------------------------- Telos EVM Main./40 |TLOS| | "The most scalable E.platform available today" └ Testnet/41 |TLOS| | Fixed gas fee. Enviro.Friendly | | | ESG compliance ---------------------|----| |----------------------------------------------------- CoinEx SmartCh./52 | CET| | PoS based. Permission-free, low fess. └ Testnet/53 |CETT| | Finance oriented ---------------------|----| |----------------------------------------------------- Ontology Main./58 | ONG| | Focus:Decentralized IDentity. Customers include └ Testnet/5851 | ONG| | Daimler Benz Mobility. | | | App User base: 50% Asia, 7% USA. | | | partnered with rOCKI, next-gen music [NFT] | | | streaming service and NFT platform built on | | | Binance Smart Chain (BSC) to use its DID solution | | | to prevent badn actors impersonating artists. | | | Multi-Virtual Machine supports. | | | "Ont. has its own VM, and also supports Wasm, NeoVM. | | | and EVM.... Devs can now use Ont.Bridge to convert | | | Ont.Native OEP4 to ORC20 tokens, adding to MetaMask, | | | and deploying dApps. ---------------------|----| |----------------------------------------------------- GoChain Main./60 | GO| | Proof of Reputation (PoR) web3 based public+private └ Testnet/31337 | GO| | 1300 TX/sec.(10000x greener, 1000x cheaper) | | | Run by Lenovo, RMIT university, Nicosia University, | | | Pennsylvania State University, ... | | | Quite active as of 2021-11 according to: | | |@[https://medium.com/gochain] | | | Clientes include Fortune 500 companies, | | | Compañía Nacional de Minería de Colombia, | | | Services include: | | | - Zeromint NFT Marketplace and Chainparency. --------------------------| |----------------------------------------------------- OKExChain Main./65 | OKT| | Decentralized Exchange (DEX) oriented, running └ Mainnet/66 | OKT| | "on top" Cosmos + EVM. ---------------------|----| |----------------------------------------------------- POA Network Core/99 | POA| | └ Sokol/77 | SKL| | ---------------------|----| |----------------------------------------------------- PrimusChain | | | └ Main./78 |PETH| | ---------------------|----| |----------------------------------------------------- Meter Mainnet/82 | MTR| | "High performance infra" allowing S.C. to └ Testnet/83 | MTR| | "travel" through heterogeneous blockchain networks. | | | Partneting with ChainLink, Harmony, Poligy, | | | Standard Tokenization Protocol, Oasis Foundation, | | | ... | | | 100+ validators. ---------------------|----| |----------------------------------------------------- Lightstreams | | | └ Mainnet/162 | PHT| | Built on Tendermint consensus ("Cosmos"). According └ Testnet/163 | PHT| | to page: a $5.63 TX in E.MainNet becomes $0.0002 in | | | lightstreams. $42.30 Uniswap reduces to $0.0016. | | | x25 faster with install 3secs. settlement. | | | Doesn't look to be very active. 1/2 post per year. ---------------------|----| |----------------------------------------------------- BitTorrent Ch./199 | BTT| | Blokchain tokenizing BitTorrent Decentralized └ Testnet/1028 | BTT| | file sharing protocol. ---------------------|----| |----------------------------------------------------- Freight Trust | | | Focus on regulated/compliant SupplyChain. Network/211 | 0xF| | EID X12, EDINT AS2/AS4, | | | EDI EDIFACT, Custom/Imports, | | | Custom/Exports, Freight Forwarders ---------------------|----| |----------------------------------------------------- Energy Web Ch./246 | ???| | https://energyweb.org/ | | | "World’s first public, enterprise-grade | | | blockchain tailored to the energy sector" | | | 46 projects in 21 countries | | | with 41 partners as of 2021-11 | | | W3C DID is used as core Identity building block. | | | ºIdentity is provided to any customer, asset,º | | | ºutility or regulator.º ---------------------|----| |----------------------------------------------------- Theta | | | Specialized in peer-to-peer (real-time)video └ Mainet /361 TFUEL| | streaming/transcoding. └ Testnet /365 TFUEL| | streaming/transcoding. Sap.Test. /363 TFUEL| | Compat. with EVM Constantinople plus Amber Test/364 TFUEL| | a couple of key Istanbul features. | | | ºGlobal partners including Google, Samsung,º | | | ºBinance, Blockchain.com, and Gumi.º ---------------------|----| |----------------------------------------------------- Acala Network/787 | ACA| | layer-1 with built-in liquidity and └ Testnet/595 |mACA| | ready-made fin.apps + trustless | | | exchange, decentralized stablecoin | | | (aUSD), DOT Liquid Staking (LDOT), | | | and EVM+. supported by Polkadot Substrate. ---------------------|----| |----------------------------------------------------- Ambros Chain |AMBR| | 600+ PoA network designed for IoT. └ MainNet/ 880 |AMBR| | 13.848 Holders. └ Testnet/8888 |AMBR| | Digital identities are given to devices, | | | with all data about their condition and | | | movement securely bundled and automatically | | | relayed to your blockchain. ---------------------|----| |----------------------------------------------------- Wanchain/888 | WAN| | https://www.wanchain.org/ └ Testnet/999 | WAN| | Finance oriented Public|Private-to-Public|Private ---------------------|----| |----------------------------------------------------- Clover Main./1023 | CLV| | part of cross-blockhain (EVM, DOT/KSM+ parachains, └ Testnet/1024 | CLV| | Solana) project. ---------------------|----| |----------------------------------------------------- MathChain/1139 |MATH| | https://mathchain.org/en/ └ Testnet/1140 |MATH| | SmartWallet AppChain based on (Polkadot) Substrate | | | Features: DID, SecretStore, EVM, Off-chain Worker. ---------------------|----| |----------------------------------------------------- Ecoball Main./??? | ECO| | Finance Oriented. Claims to support 100.000 TX/s └ Test.Espuma/??? | ECO| | using VPoS and smart-node selection with close-to-zero | | | trading fees. | | | 25 validator pools and 245 delegators. ---------------------|----| |----------------------------------------------------- QuarkChain | | | flexible, scalable, user-oriented └ Mainnet | | | blockchain infrastructure by using └ Root/100000 | QKC| | blockchain sharding technology. └ Shards/*1 | QKC| | └ Devnet └ Root/110000 | QKC| | └ Shards/*2 | QKC| | *1:100001..8 | | | *2:100001..8 | | | ---------------------|----| |----------------------------------------------------- Harmony | | | 2-second TX finality @ 1/1000 price. └ Mainnet | | | Open platform for assets, collectibles, └ Shards/*1 | ON| |E identity and governance. └ Testnet | | | secure bridges offer cross-chain asset └ Shards/*2 | ON| |E transfers with E.MainNet, Binance and 1666600000..3 | | | 3 other chains. 1666600000..3 | | | daVinci NFT marketplace: April 2021. | | | ---------------------|----| |----------------------------------------------------- IoTeX Network | | |@[https://iotex.io/] └ Mainnet/4689 |IOTX| | 9K+ DEVICES 200K+ COMMUNITY └ Testnet/4690 |IOTX| | 14,4M TRANSACTIONS 39,000+ STAKERS | | | """IEEE Blockchain⅋ IoT Standards | | | Working Group Appoints IoTeX Head of | | | Cryptography as Vice Chair """ | | | ---------------------|----|-|----------------------------------------------------- Binan.SmartCh./56 | BNB|Y| PoSA = Proof of Stake + Proof of Authority. └ Testnet/97 |tBNB| | RºWARN:º"Spam Chain". Very active on Twitter an press Completely broken in Real World: @[https://github.com/binance-chain/bsc/issues/553] OTHERS Networks: @[https://chainid.network/] Diode , Flare , ThunderCore, Callisto, ... -------------------------------------------------------------------------------------------------
Related Taxonomies
Bº##########################º
Bº# TokenTaxonomyFramework #º
Bº##########################º
@[https://github.com/InterWorkAlliance/TokenTaxonomyFramework]
@[https://interwork.org/real-world-tokens-a-seven-step-journey-into-the-ttf/]

Bº#################º
Bº# Laws Taxonomy #º
Bº#################º
@[https://law.stackexchange.com/tags]


Bº######################º
Bº# Economics Taxonomy #º
Bº######################º
@[https://economics.stackexchange.com/tags]

EVM
External Refs:
@[https://github.com/ethereum/yellowpaper]
@[https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial]
@[http://ethdocs.org/en/latest/contracts-and-transactions/developer-tools.html#the-evm]
Patricia tree
@[https://eth.wiki/en/fundamentals/patricia-tree] 

• cryptographically fully deterministic "key/value":
  A Patricia trie: cryptographycally protected (key,value) store with 
  O(log(n)) inserts/lookups/deletes.
  Much easier to understand and code than alternatives (red-black tries).

• Ethereum use Merkle Patricia Tries (with roots hashed stored in block-header) for:
  ✓ºroot-of-state:º *1
    · trie-path : sha3(ethereumAddress)
    · trie-value: rlp(ethereumAccount) ← nonce, balance,✓root-of-contract-storage, codeHash
                                                    └───────────┬──────────┘
                                                    trie-path : sha3(position-of-variable) 
                                                    trie-value: rlp-encoding of storage value

  ✓ºroot-of-transactions:º
    · trie-path : rlp(transactionIndex)
    · trie-value: rlp(transaction)?
  ✓ºroot-of-receipts:º
    · trie-path : rlp(transactionIndex)
    · trie-value: rlp(receipt)?

  *1:ºEVM stateº:
    @[https://blog.ethereum.org/2019/12/30/eth1x-files-state-of-stateless-ethereum/]
    - 400 million nodes in the state trie. Of these, about 3,000 (but as
      many as 6,000) need to be added or modified every 15 seconds.
      Staying in sync with the Ethereum blockchain is, effectively,
      constantly building a new version of the state trie over
      and over again.
       ... This multi-step process of state trie database operations is why
      Ethereum implementations are so taxing on disk I/O and memory, and
      why even a “fast sync” can take up to 6 hours to complete, even
      on fast connections. To run a full node in Ethereum, a fast SSD (as
      opposed to a cheap, reliable HDD) is a requirement, because
      processing state changes is extremely demanding on disk read/writes.

Implementation Notes • RADIX-TRIE, BASIC BUILDING BLOCK OF PATRICIA TIRE: º####################################################º º# PRE-SETUP) CHOOSE AN ORDERED ALPHABET. #º º# (Hex digits "nibles" in Ethereum implementation) #º º####################################################º ┌─ NODE "micro─db" ──────────────────────────────────────┐ │ 0 1 2 3 4 5 6 7 8 9 A B C D E F ← ORDERED (IMPLICIT) │ · · · · · · · · · · · · · · · · │ POSITION GIVEN AN │ · · · · · · · · · · · · · · · · │ INITIAL ORDERED ALPHABET │ [p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,value]│ └─ └──────────────────────┬──────────────────────┘ └─┬─┘─┘ array containing values (keys are implicits, "information" based on order-of-array = order-of-alphabet) located-in-order @end-of-array KEY-POINT: trie must be built/calculated "upside-down": leaf nodes first, then its leaf-parent, then leaf-grandparents, ... finally the root-node. • p0..pF values := NULL|sha3(rlp(pointed-node)) └─┬─┘ "Merkle part" of the Patricia trie. KEY POINTs: It root-hash is publicly known, then anyone can provide a proof that the trie has a given value and nobody can provide a false proof for non existing key-values pairs. • To fetch the value of key "dog" in trie: STEP 1) dog → (to alphabet) → 646F67 ······························┐ STEP 2) Walk over trie path: · 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] root-node · ┌────────────┘ · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] node[0][6] · ┌────────┘ · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] node[0][6][4] · ┌────────────┘ · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] node[0][6][4][6] · ┌──────────────────────────────┘ · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] node[0][6][4][6][F] · ┌────────────┘ · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] node[0][6][4][6][F][6] · ┌──────────────┘ · [?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,value] node[0][6][4][6][F][6][7] ←┘ └─┬─┘ ?: hash-of-pointed-node dog value!!! PROBLEM: radix tries are inefficient: a bytes32 needs 64 chars long or over a kilobyte of extra space to store one level per character. each lookup/delete will take the full 64 steps. SOLUTION: PATRICIA TRIE TO THE RESCUE. • PATRICIA TRIE: • Most nodes in the radix-trie will be "empty" (no value) in a 64 chars path. Forcing them to have empty values in every index + "target" index is a waste. Patricia Trie node extension add next structures: • encodedPath: "partial path" shortcut to skip ahead using compact encoding. Then the Patricia Trie node wil be one of : - NULL node: (represented as "empty string") - branch A node: [ v0, ...,vF, vt ] - extension A 2-item node: [ encodedPath, key ] ← key: used for next db-lookup - leaf A 2-item node: [ encodedPath, value ] ← a flag in 1st nible of encoded path marks node as being a leaf. • note: To differentiate among nibble 1 and nibble 01, both stored as "01", a partial path is prefixed with a flag for odd-cases. (See original post for more info)
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º │
├─────────────────────────┤
│wei            ºbalanceº │
├─────────────────────────┤
│Map˂256b,256b˃ ºstorageº │
└─────────────────────────┘

         ┌────────────────────────────────────┬───────────────────────────────────────┐
         │   EXTERNALLY OWNED ACCOUNT         │          CONTRACT ACCOUNTS            │
┌────────┼────────────────────────────────────┼───────────────────────────────────────┤
│CREATION│→ Generate random 32bytes priv. key │→Create smart─contract source code  *1 │
│        │→ Generate Pub.Key from Priv.Key    │→Generate bytecode by compiling source │
│        │→ Generate public address as:       │→Send "Contract Creation" TX for mining│
│        │  bytes[32] pub.addr= hash(pub.addr)│→keep Contract address once "published"│
│        │                                    │ (determined from nonce)               │
├────────┼────────────────────────────────────┼───────────────────────────────────────┤
│CONTROL │Private Key: Only the (human) owner │ BYTECODE                              │
│BY      │of the ºsecretº private key can     │                                       │
│        │decrease the balance by signing 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
(EVM CALL opcode)
- Contracts can user message calls to call other contracts or send Ether to
 non-contract accounts.

      ETHEREUM NETWORK
       o······o······o
       ·      ·      · Oº─ → ─º Gossip Protocol
       o      o─Oº→º─o
       ·    Oº↑      ↓º
local→ o─Oº→º─o······O ← Mining
node        ↑        │   node
       │           ┌─┘
       │           │
       │           │ Signed TX is mapped to the top─level
ºSigned TXº        │ message call by Mining Node
       ↑   ┌───────│────────────────────────────────── EVM executing at Mining Node ──┐
┌──────┴─┐ │       ↓                     ┌─────┐                               ┌─────┐│
│external│ │      top─level              │sc01 │                               │sc02 ││
│client  │ │      message call       ──→ │funcA│  → message call ────────────→ │funcB││
└────────┘ │                             └─────┘                               └─────┘│
           │      ───────────────          │  ^     ────────────                  │   │
           │      sender  = tx signer addr │  │     sender  = sc01.addr           │   │
           │      target  = sc01.addrº*1º  │  │     target  = sc02.addr           │   │
           │      payload = abi(funcA+args)│  │     payload = abi(funcB+arggs)    │   │
           │      value   = 0+gweis        │  │     value   = 0+gweis             │   │
           │      gas     = *2             │  │     gas     =º*2º                 │   │
           │  º*3ºreturn data  ←───────────┘  └──── return data  ←────────────────┘   │
           └──────────────────────────────────────────────────────────────────────────┘

 º*1º: target can also be an external (non-contract) account (or even == "sender")

 º*2º: Enough gas to execute called function, but small enought to avoid
       wasting too-much ethers (because of software bugs, gas-price, ...)
       Contracts decide how much remaining gas is sent within calls to other
       contracts.
     BºAn (out-of-gas|*) exception in inner message call is signalled by anº
     Bºerror value put onto the stack.                                     º
     BºThe gas sent is consumed. º
     BºBy default in  Solidity calling contract re-launch a manual exception º
     Bºto make exceptions "bubble up" the remote call stack.º

 º*3º: return data is stored at ºpreallocated locationº in caller's memory.
     Rºreturn data of top-level call is not usedº, since client disconnects as
       soon as local node cofirms Signed TX reception.
       sc01.funcA will use async Events to communicate results.
       (original external client and any other interested cliet will listen for
        such events)

 - Calls depth is limited to 1024 (Prefer loops to recursive calls)

DELEGATE CALL
( EVM DELEGATECALL opcode, Homestead+ )
- mostly indentical to a message call BUT
  - called code is executed in the context of the calling contract
    - sender == original msg.sender
    - value  == original msg.value
    - Same storage
    - Same current balance
    - Different Code / Different Program Counter
    - New function stack

- Used in libraries, since it allows a contract to dynamically load code
  from a different address at runtime.
  For example to manipulate Complex data structures.
  Library code is deployed once at a specific address and their code invoqued
  through DELEGATECALL.
  BºIn comparison to contracts, libraries:º
  Bº- Have no state variables. A reference to struct must be passed.º
  Bº- Can NOT inherit nor be inheritedº
  Bº- Can NOT recieve Etherº

- Could represent a Rºsecurity riskºfor calling contract
  whichRºneeds to trust that the receiving contractº while
  manipulating its own storage.

- Replaces Rºdeprecated CALLCODEº fixing bug since CALLCODE did not
  preserve msg.sender and msg.value.
EVM Summary

- Ethereum Virtual Machine Opcodes low level reference to EVM:
 @[https://ethervm.io/]
- EVM Illustrated (TODO)
  @[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

Bº##############º
Bº# EVM Memory #º
Bº##############º
- 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
- See also: @[#solidity_storage_magging]

Bº#############º
Bº# EVM Stack #º
Bº#############º
- 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
REF: 
@[https://github.com/ethereum/go-ethereum/blob/master/core/vm/instructions.go]
- EVM works with next inputs:
  Prog.Counter(PC): to known where to fetch next EVM instruction to execute 
                    in units of 32 bytes (0x20 bytes).
  Contract Context: To know where contract state is in storage.
  EVM "RAM" Memory: Input/Output  for Operations.
  STACK           : input/Out for Operations 

• EVM executes code start-to-end from zero address (vs some other defined/parametrizable entry point).

  
• EVM OPCODES: REF: https://www.ethervm.io/ {
                    COND.ARIT. END-  DESCRIPTION
                    TIO- ME-  FUNC/ 
                    NAL  TIC  COMP. 
  --------------------------------- BASIC ARITMETHIC
  • ADD/SUB/MUL    |    |    |    | (uint256 values) 
    DIV/SDIV       |    |    |    | SDIV == Signed division
    EXP            |    |    |    | EXP a b  == a ** b 
    SIGNEXTEND     |    |    |    | SIGNEXTEND b x y ==  y = sign extends x from (b + 1) * 8 bits (up to 256 bits).
  --------------------------------- MODULAR ARITMETHIC
  • MOD/SMOD       |    |    |    | MOD a b = a % b, SMOD == signed mod.
    ADDMOD/MULMOD  |    |    |    | ADMOD  a b N == (a + b) % N 
                   |    |    |    | MULMOD a b N == (a * b) % N
  • NOT            |    |    |    |
  --------------------------------- BYTE RELATED OPERATIONS
  • BYTE           |    |    |    | BYTE i x y ==  y = (x ˃˃ (248 - i * 8)) ⅋  0xFF
                   |    |    |    | ith byte of (u)int256 x, counting from most significant byte
  • SHL/SHR/SAR    |    |    |    | 256-bit Shift left / right
                   |    |    |    | SAR: int256 (aritmetic) shift right 
  • SHA3           |    |    |    | SHA3 offset length  == keccak256(memory[offset:offset+length])
  --------------------------------- TX ACCOUNT RELATED DATA 
  • ADDRESS        |    |    |    | "this". address of executing contract
    BALANCE        |    |    |    | address(addr).balance in wei
    SELFBALANCE    |    |    |    | address(this).balance in wei (v.Istanbul+/EIP-1884)
    ------------------------------- EXTERNAL INPUT FUNCT. INVOCATION
                                    (DATA COMMING FROM "OUTSIDE" THE EVM
    ORIGIN         |    |    |    | ORIGIN tx.origin  ==  transaction origin address
  • CALLER         |    |    |    | == "msg.caller" (EOA or contract) address.
    CALLVALUE      |    |    |    | TX "funds" in wei
    CALLDATALOAD   |    |    |    | CALLDATALOAD i  read (u)int256 msg.data[i:i+32] from message data
    CALLDATASIZE   |    |    |    | message data length in bytes
    CALLDATACOPY   |    |    |    | CALLDATACOPY destOffset offset length. Copy message data like:
                   |    |    |    | memory[destOffset:destOffset+length] = msg.data[offset:offset+length]
    ------------------------------- RETURN VALUE FROM FUNCTION
    RETURNDATASIZE |    |    |    | size-in-bytes of returned data from last external call (v.Byzantium+/EIP-211)
    RETURNDATACOPY |    |    |    | copy returned data (v.Byzantium+/EIP-211) 
                   |    |    |    | memory[dst_offset:dst_offset+length] = RETURNDATA[offset:offset+length]
    ------------------------------- Reading Smart Contract Code
  • EXTCODESIZE    |    |    |    | address(addr).code.size for param addr.
    CODESIZE       |    |    |    | address(this).code.size
    EXTCODECOPY    |    |    |    | EXTCODECOPY addr dst_offset offset length. copy contract's bytecode like: 
                   |    |    |    | memory[dst_offset:dst_offset+length] = address(addr).code[offset:offset+length]    
    CODECOPY       |    |    |    | CODECOPY dst_offset offset length  copy executing contract's bytecode like:
                   |    |    |    | memory[dst_offset:dst_offset+length] = address(this).code[offset:offset+length]    
    ------------------------------- BLOCK RELATED RUNTIME PARAMS.
  • EXTCODEHASH    |    |    |    | EXTCODEHASH addr hash = address(addr).exists ? keccak256(address(addr).code) : 0  (v Constantinople +/ EIP-1052)
    BLOCKHASH      |    |    |    | BLOCKHASH block hash    hash = block.blockHash(block), only valid for 256 most recent blocks excluding current one
    COINBASE       |    |    |    | current block's miner (injected from miner's ethereum config at node startup)
    DIFFICULTY     |    |    |    | current block.difficulty (established by network consensus)
    GAS            |    |    |    | return remaining gas
    GASLIMIT       |    |    |    | current block.gaslimit (established by network consensus)
    GASPRICE       |    |    |    | tx.gasprice established by signer in wei-per-unit-of-gas
    NUMBER         |    |    |    | current block.number
    TIMESTAMP      |    |    |    | current miner block's Unix timestamp in seconds
    CHAINID        |    |    |    | 1: mainnet, 2 Morden testnet(disused),2 Expanse mainnet, 3 Ropsten testnet, 4 Rinkeby testnet 
    CHAINID        |    |    |    | 5: Goerli testnet, 42: Kovan testnet (v.Istanbul+/EIP-1344)
    BASEFEE        |    |    |    | v.London+/EIP-3198
    ------------------------------- MEMORY READ/WRITE FROM/TO STACK
  • MLOAD          |    |    |    | MLOAD  offset value  (u)int256 value = memory[offset:offset+32]
    MSTORE         |    |    |    | MSTORE offset value  memory[offset:offset+32] = (uint256) value
    MSTORE8        |    |    |    |                      memory[offset] = value ⅋ 0xFF
    MSIZE          |    |    |    | return size-in-bytes of memory for this contract execution.
  --------------------------------- STACK OPERATIONS
  • ISZERO         |    |    |    | Push 1 if topmost value is zero
    DUP1/2/../17   |    |    |    | clone 1st/2nd/3rd/... element in stack with "0th"
    SWAP1..17      |    |    |    | Swap  1st/2nd/3rd/... element in stack with "0th"
    PUSH1/.../33   |    |    |    |PUSH 1/2/3/.../33 byte value onto start 
    POP            |    |    |    | pops and discard (u)int256 from stack.
  --------------------------------- CONTRACT STORAGE
  • SLOAD          |    |    |    | SLOAD  key value, (u)int256 value = storage[key] (read from storage)
    SSTORE         |    |    |    | SSTORE key value, storage[key] = value
  • LT/GT/SLT/SGT/ |XXXX|    |    | 
    EQ/ISZERO      |    |    |    |
  • AND/OR/XOR     |XXXX|    |    | 256-bit bitwise ops
  --------------------------------- PC CONTROL "JUMP" OPERATIONS.
  • JUMP           |    |    |    | read-and-pop topmost stack-value, then "jumps" Program Counter to read value.
    JUMPI          |XXXX|    |    | jump condition if 2nd value in stack is NOT "0". (Consume 2 stack values)
  • JUMPDEST       |    |    |    | Target location must contain JUMPDEST opcode (otherwise exec. 
                   |    |    |    | fails). This checking is the sole purpose of JUMPDEST, mark
                   |    |    |    | location as valid jump target).
  • PC             |    |    |    | Program counter value
  --------------------------------- FUNCTION INVOCATION
    CALLCODE       |    |    |    | gas addr value args_offset args_length ret_offset  ret_length. call method IN this contract?
    CALL           |    |    |    | gas addr value args_offset args_length ret_offset  ret_length. call method IN ANOTHER CONTRACT
    DELEGATECALL   |    |    |    | gas addr       args_offset args_length  ret_offset ret_length. call method IN ANOTHER CONTRACT
                   |    |    |    |                                                                using current storage (v.Homestead+/EIP-7)
    STATICCALL     |    |    |    | gas addr       args_offset args_length  ret_offset ret_length. call method IN ANOTHER CONTRACT 
                   |    |    |    |                                                                with state changes disallowed
                   |    |    |    |                                                                (v.Byzantium+/EIP-214)
  • RETURN         |    |    |X   | offset length , Returns data from a portion of the EVM's memory. (return memory[offset:offset+length])
  --------------------------------- TX ABORT
  • REVERT         |    |    |X   | REVERT  offset  length  -   revert(memory[offset:offset+length])    Byzantium hardfork, EIP-140: reverts with return data FE  Invalid     -   -   -   -
  • STOP           |    |    |X   |unconditional halts execution 
  --------------------------------- TX ABORT
  • LOG0...4       |    |    |    | Output Log (Indexed event) generation readable by clients 
                   |    |    |    | LOG0(memory[offset:offset+length])  fires an event
                   |    |    |    | LOG1(memory[offset:offset+length], topic0)  fires an event
                   |    |    |    | LOG2(memory[offset:offset+length], topic0, topic1)  fires an event
                   |    |    |    | LOG3(memory[offset:offset+length], topic0, topic1, topic2)  fires an event
                   |    |    |    | LOG4(memory[offset:offset+length], topic0, topic1, topic2, topic3)  fires an event(vs OpCodes)
  --------------------------------- CONTRACT LIFE CYCLE
  • SELFDESTRUCT   |    |    |    | SELFDESTRUCT addr, destroy "this" contract, then sends all remaining funds to "addr".
  • CREATE2        |    |    |    | value offset length salt addr.  addr = new memory[offset:offset+length].value(value)
                   |    |    |    | (v.Constantinople+/EIP-1014). Creates child contract with deterministic address
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
ºEVM Events:º
 • In the wild, there are three main uses for event logs:
   - As external apps return values, because a transaction does not record a
     method's return values, only the hash confirming the transaction.
   - As a kind of cheaper alternative data storage, as long as the
     contract does not need access to it.
     According to the Yellow paper:
     "...There is no size limit to the data: you will be limited by how
         much Ether you have. (And of course the block gas limit.).The size
         limit of one event is a function of the block's gas limit, which as
         of now tends to be around 3,145,192 (i.e., the first seven digits of
         pi). According to Jonathan Patrick, logging costs 76 gas per byte. So
         I'd assume you could get in around 41kb per log event...."
   - Output evm device sending Event data that DApp clients can subscribe to.

 • Emiting an event is a simple EVM logging primitives (log0, log1, ..., log4) 
   and a single Solidity 
 
    - The EVM logging facility uses different terminologies than Solidity:

   instruction. e.g.:
   // Solidity event declaration:
   event accountDeposit( address indexed _from, bytes32 indexed _id, uint _value);
   ...
   // Solidity event emission:
   emit  accountDeposit( _from, _id, _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.

   "topics": (event indices). There may be up to 4, 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.

 - NOTE: Internally Ethereum nodes use bloom indexes/filters to implement topics and
         topic search in order to speed up search-by-topic.


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
Solidity←→storage address
REF: @[https://www.mayowatudonu.com/blockchain/deep-dive-into-evm-memory-and-storage]
  contract BlockVoting {
    Period[] dynArray01;        ← Idx 0x00..32bytes/64 hex-digits ...00
                                      - array length stored in next available slot
                                      - array data allocated at a slot number:
                                        hash of n(keccak256(n))
    uint public voteThreshold;  ← Idx 0x00..32bytes/64 hex-digits ...01
    mapping(uint8   =˃ bool)    ← Idxº0x00..32bytes/64 hex─digits ...02º ←·············┐
      public map01;                   - slots are unused,                              ·
                                      - value for each key located at keccak256(n, p)←─┤
                                                                                ^  ^   ·
                                                                left padded to 32 bytes·
    uint8[] dynArray01;         ← Idx 0x00..32bytes/64 hex-digits ...                  ·
    ...                                                                                ·
    constructor () public {           $ truffle˃ compile                               ·
         voteThreshold = 10;          $ truffle˃ BlockVoting.new()                     ·
         dynArray01.push(20);                    .then(item =˃ instance = item;)       ·
         dynArray01.push(30);         $ truffle˃ web3.eth                              ·
         dynArray01.push(56);                    .getStorageAt(instance.address, 0)    ·
         map01[1] =  5;  ←······┐     '0x0a' (== 10)$                                  ·
                                · ┌····················································┘
                                · ├ $ truffle(dev)˃ºn = '00..32bytes/64 hex-digits ...02'º
                                · ├ $ truffle(dev)˃ p = 'x0..32bytes/64 hex-digits ...01'                        
                                · ├ $ truffle(dev)˃ hash01 = web3.sha3(n + p, {encoding: 'hex'})                        
                                · │ 0xaca3b76ed4968740c3180dd7fa37f4aa229a2c758a848f53920e9ccb4c4bb74e                        
                                · └ $ truffle(dev)˃ web3.eth.getStorageAt( instance.address, hash01)                        
                                └ '0x05'                                                    ...             
    }
  }

• NOTE: This can be used to pre-fill a hardcoded smart-contract 
        with given status in genesis.json block:

  "alloc": {
    "0x0000000000000000000000000000000000000020": {
      "code": "0x6060604...6",
      "storage": {
        "0x0000000000000000000000000000000000000000000000000000000000000001": "0x02", ← Assign voteThreshold = 02
        "0x29ecdbdf95c7f6ceec92d6150c697aa14abeb0f8595dd58d808842ea237d8494": "0x01", ← dynArray01(1)
        "0x6aa118c6537572d8b515a9f9154be55a3377a8de7991cd23bf6e5ceb368688e3": "0x01", ← dynArray01(1)
        ....
        "0xaca3b76ed4968740c3180dd7fa37f4aa229a2c758a848f53920e9ccb4c4bb74e": "0x01"  ← Assign canVote[...]=0x01
        "0xd188ba2dc293670542c1befaf7678b0859e5354a0727d1188b2afb6f47fe24d1": "0x01"  ← Assign canVote[...]=0x01
      },
      "balance": "0"
    },
    ...
  }
Transactions
  NOTE:
  a client Transaction 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. Client Dapps (web-app/mobile app) must react asynchronously to 
  future events. Only when the transaction is inserted in a block (and some future 
  works have been mined -in non consensus with statistical finality -) it is considered 
  as a valid transaction.
  ┌ ETHEREUM TRANSACTION ────┐  TX is encoded as   "RLPdata" (nonce,gasPrice,startGas,to,value,data) 
  │                          │                   + signature (r, s, v)
  ├──────────────────────────┤
  │ • signature tuple        ←  EOA-wallet valid signature. Signature address must match "from"
  │                          │  sign.tuple == (signature_hash, v, r, s) º*1 Signature Detailsº
  ├──────────────────────────┤
  │ • EOA-last-nonce + 1     ←  increasing counter avoid replay attacks. Multiple versions of
  │                          │  a TX can be sent with a repeated nonce overwriting pending TX.
  │                          │  Once mined, a submissions will be rejected.
  │                          │  
  │ • address sender ("from")←  Must match EOA-address in TX signature, as a proof that from 
  │                          │  is actually willing to pay for TX.
  │                          │
┌ │ • address target ("to")  ←  If to == 0            : it means "create contract"
│ │                          │  if to == EOA          : standard wallet-to-wallet payment
│ │                          │  if to == (deployed) SC: Write/Modify/Update Function invocation.
│ │                          │  NOTE: Read-only queries (view/pure functions) do not need a TX
│ │                          │        An standard JSON-RPC with func.params query is enough.
├ │ • byte[]  code("payload")←  if target == 0: compiled bytecode factory for contract.
│ │                          │  Otherwise abi-encoded function call. If encoded function (selector)
│ │                          │  doesn't match any function in S.C. code, its fallback function will
│ │                          │  be invoqued. Otherwise, an exception will be raised. 
│ │ • wei ether              ←  ether sent/paid to target/"to"
│ │                          │
│ │                          │
│ │ • wei gasPrice           ←  desired gas price TX signer will pay to miners for º1-unit-of-gasº
│ │                          │  when running code. OºUsed by miners to prioritize TXsº.
│ │                          │
│ │ • wei gas                ←  When multiplied by TX.gasPrice == desired max.Ether to pay 
│ │                          │  for executing TX. Its purpose is to limit max. 
│ └──────────────────────────┘  amount-of-work needed to execute invoqued S.C. code.
│                                                           
└ if target == "zero" then:
     step 1: new contract created
     step 2: transaccion.payload executed
     step 3: exec. output stored on-chain at (contract)account.code

 º*1º Signature Details: @[https://medium.com/@angellopozo/ethereum-signing-and-validating-13a2d7cb0ee3]
   - SECP256K1 (one of the ECDSA supported algorithms) is used for signature. 
     SECP256K1 Output signature is composed of two integers (r,s) but SECP256K1 ETH/BTC library, however,
     defines the public key as (r, s, v), where v := 0|1. (v is called the recovery id).
     when public key is derived ºfrom the signatureº two solutions surge and v is needed.
     - if derived-public-key length is 64 bytes (r,s)   is used.
     - if derived-public-key length is 65 bytes,(r,s,v) is used.
     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]]

     · 'ecrecover': Solidity Global Crypto Funct can be used to recover the address given the signature. 
       function ecrecover
      º(bytes32 signature_hash, uint8 v, bytes32 r, bytes32 s)º
       view
      ºreturns (address)º  ← Original address associated with the public key (zero on error)
                             Can be used for N/M signatures (See @[#eip-191])

     - NOTE: The use of Curve25519 with Schnoor signing scheme (Ed25519) is under discussion

     - NOTE: Only Externally Owned Accounts can sign transactions. EIP-1271 offers a 
       "abstraction" of signature as described in @[eip-1271].



OºTX SENDER-to-MINER PAYMENT RULES:º
  • If ( execution gas ˂ transaction.gas ) { Refund rest to sender }
  • If ( execution gas ˃ transaction.gas ) {
      · out-of-gas exception triggered. 
      · modifications made to the state in current call frame reverted.
      · TX is still mined, and weis lost BUT there is no state change.
    }
  

BºBLOCK VALIDATION ALGORITHM (CONSENSUS)º
Bº======================================º
  - Check if previous block referenced exists and is valid
  - Check ( last_block.timestamp ˂ new_block.timestamp ˂ lst_block.timestamp + 15 minutes )
  - Check block-number, difficulty, transaction root, uncle root and gas limit
    (various low-level Ethereum-specific concepts) are valid.
  - Check that proof-of-work 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 application returns error, or
    if the total gas consumed in the block up until this point exceeds consensus 
    constant BLOCK.GASLIMIT, return error.
  - Let S_FINAL be S[n], but adding the block reward paid to the miner.
  - Check if S_FINAL == STATE_ROOT. 

EIP-191: Signed Data Standard (Multisignature TXs)
- EIP-191: Signed Data Standard 
@[https://eips.ethereum.org/EIPS/eip-191]
@[https://github.com/ethereum/EIPs/issues/191]
- See also @[#eip-712]

  - Several multisignature wallet implementations have been created 
    which accepts presigned transactions (chunk of binary signed_data, 
    along with signature (r, s and v) ). 
    interpretation of the signed_data has not been specified, leading to 
    several problems.
    - Standard Ethereum transactions can be submitted as signed_data.
    - An Ethereum transaction can be unpacked, into:
      - RLP˂nonce, gasPrice, startGas, to, value, data˃ (called RLPdata),
      - r, s and v. 

  - Multisignature wallets have also had the problem that a presigned 
    transaction has not been tied to a particular validator, i.e a specific
    wallet. Example:
    · Users A, B and C have the 2/3-wallet X
    · Users A, B and D have the 2/3-wallet Y
    · Users A and B submites presigned transaction to X.
    · Attacker sends presigned transactions to Y (instead of X).

Example code:
@[https://github.com/0xsequence/erc-1155/blob/master/SPECIFICATIONS.md#meta-transactions]


EIP-4361: Using EIP-191 for Offchain client Auth. @[https://github.com/spruceid/EIPs/blob/eip-4361/EIPS/eip-4361.md] @[https://ethereum-magicians.org/t/eip-4361-sign-in-with-ethereum/7263/2] - Scenario: "https://service.org" wants to authenticate user through its Ethereum account: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 ┌─ Example message to be signed ────────────────────────────────────────┐ │ I accept the ServiceOrg Terms of Service: https://service.org/tos │ │ │ │ URI: https://service.org/login │ │ Version: 1 │ │ Chain ID: 1 │ │ Nonce: 328917 │ │ Issued At: 2021─09─30T16:25:24Z │ │ Resources: │ │ ─ ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ │ │ ─ https://example.com/my─web2─claim.json │ └───────────────────────────────────────────────────────────────────────┘ - For EOAs verification method in EIP-191 MUST be used. - For Contract Accounts verification method in EIP-1271 MUST be used.
TX Gas Price
• REFs:
  @[https://github.com/ethereum/wiki/wiki/Design-Rationale#gas-and-fees]
  @[http://www.ethdocs.org/en/latest/contracts-and-transactions/account-types-gas-and-transactions.html?highlight=gas#what-is-gas]
• Gas rationale:
  · Gas protect against DoS attacks and buggy nodes, EVMs, and/or smart-contracts.
  · Price cost applies to public network and (optionally) to private/consortium networks.
    NOTE: private/consortium networks will still be constrained to
          gas limits even when gas price is ZERO. [TODO]: Recheck
  · TXs will fail if the consume too much gas ("CPU" or storage)
  but users will not loose any ethers when price is set to ZERO.


• See gas consumption per OpCode: 
@[https://github.com/ethereum/pyethereum/blob/master/ethereum/opcodes.py]
  # NON-OPCODE GAS PRICES
  GDEFAULT           =     1
  GMEMORY            =     3
  GQUADRATICMEMDENOM =   512  # 1 gas per 512 quadwords
  GSTORAGEREFUND     = 15000
  GSTORAGEKILL       =  5000
  GSTORAGEMOD        =  5000
  GSTORAGEADD        = 20000
  GEXPONENTBYTE      =    10 # cost of EXP exponent per byte
  GCOPY              =     3 # cost to copy one 32 byte word
  GCONTRACTBYTE      =   200 # one byte of code in contract creation
  GCALLVALUETRANSFER =  9000 # non-zero-valued call
  GLOGBYTE           =     8 # cost of a byte of logdata
  
  GTXCOST            = 21000 # TX BASE GAS COST
  GTXDATAZERO        =     4 # TX DATA ZERO BYTE GAS COST
  GTXDATANONZERO     =    68 # TX DATA NON ZERO BYTE GAS COST
  GSHA3WORD          =     6 # Cost of SHA3 per word
  GSHA256BASE        =    60 # Base c of SHA256
  GSHA256WORD        =    12 # Cost of SHA256 per word
  GRIPEMD160BASE     =   600 # Base cost of RIPEMD160
  GRIPEMD160WORD     =   120 # Cost of RIPEMD160 per word
  GIDENTITYBASE      =    15 # Base cost of indentity
  GIDENTITYWORD      =     3 # Cost of identity per word
  GECRECOVER         =  3000 # Cost of ecrecover op
  
  GSTIPEND           =  2300
  
  GCALLNEWACCOUNT    = 25000
  GSUICIDEREFUND     = 24000

• Theºmost expensive operations by far are storage onesº:
  ┌─────────────┬───────┬────────────────────────────────────────────┐
  │Operation    │   Gas │ Remark                                     │
  │Name         │ Spent │                                            │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │step         │     1 │ default amount per execution cycle         │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │stop         │     0 │ free                                       │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │suicide      │     0 │ free                                       │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │self-destruct│-24000 │                                            │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │sha3         │    20 │                                            │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │sload        │    20 │ get 32-bytes from permanent storage        │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │sstore  op   │   100 │ put 32-bytes into permanent storage        │
  │             │       │ (+ ~ 20000 by setting     zero → non-zero) │
  │             │       │ (- ~ 10000 by setting non-zero → zero)     │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │balance      │    20 │                                            │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │create       │   100 │ contract creation                          │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │call         │    20 │ initiating a read─only call                │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │memory       │     1 │ every additional word when expanding memory│
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │txdata       │     5 │ every byte of data or code for a TX        │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │transaction  │   500 │ base fee transaction                       │
  ├─────────────┼───────┼────────────────────────────────────────────┤
  │contract     │ 53000 │ changed in homestead from 21000            │
  │  creation   │       │                                            │
  └─────────────┴───────┴────────────────────────────────────────────┘
  - Most instructions costs 3~10 gas.
  - Gas costs are set somewhat arbitrarily, and will change/adapt in the future.
  - As costs change, compilers will make different choices.

• TX cost:
  @[https://medium.com/@hayeah/how-to-decipher-a-smart-contract-method-call-8ee980311603]
  ✓ 21000 gas per TX (fixed cost)
  ✓     4 gas per     zero-byte of data|code
  ✓    68 gas per non-zero-byte of data|code
  RºWARNº: Small negative numbers are mostly 1s, costing quite a lot of gas.

• LOGGING (INMUTABLE EVENTS) GAS COSTS:                        [events]
@[https://blog.qtum.org/how-solidity-events-are-implemented-diving-into-the-ethereum-vm-part-6-30e07b3037b9]
  • gas costs for evm logging primitives depends on number of topics (indexes)
    and payload length:
    (constants are defined in protocol_params)

    ✓   8 gas per byte in a LOG operation's data LogDataGas
    ✓ 375 gas per LOG                            topicLogTopicGas
    ✓ 375 gas per LOG operation                  LogGas
    ✓   3 gas per byte of payload                MemoryGas

    ✓ ??? gas per data in calldata if source log
          data comes from mined TX
          (4 gas per zero-byte, 64 per non-zero-byte)

    BºHINTº: event with all non-zero bytes called from external
             TX it is still a lot cheaper than storage.
             • 3200 no-zero-bytes log gas RºTX FIXED COST(log or sstore)º:
               (external signed TX sent from wallet/client dApp)

               Concept                     Unit *         Sub
                                           Unit-cost      Total
               ─────────────────────────────────────────────────
               TX cost                    |   1 * 21000 |  21000
               external tx non-zero-bytes |3200 *    68 | 217600 ← TIP: optimize non-zero-bytes
               TX data|code byte          |3200 *     5 |  16000
                ────────────────────────────────────────────────
                                                  TOTAL   254600

             • 3200 no-zero-bytes log gas bill:
               Most gas cost is TX data, not log ops itself.

               Concept                     Unit *            Sub
                                           Unit-cost       Total
               ─────────────────────────────────────────────────
               TX FIXED COST              |   1 * 254600| 254600 ← Most gas cost is TX data,
               log-data-cost              |3200 *      8|  25600   TIP: optimize input data
               memory usage cost          |3200 *      3|   9600
               log call cost              |   1 *    375|    375
               ─────────────────────────────────────────────────
                                                  TOTAL   290175 ~ 7.8 times cheaper

             • 320 no-zero-bytes sstore bill:
               Concept                     Unit *            Sub
                                           Unit-cost       Total
               ─────────────────────────────────────────────────
               TX FIXED COST              |   1 * 254600| 254600
               memory usage cost          |3200 *      3|   9600
               sstore op                  | 100 *    100|  10000
               sstore zero → non-zero     | 100 *  20000|2000000
               ─────────────────────────────────────────────────
                                                  TOTAL  2274200
             • The real reason is for lower prices is that log data is NOT
               really stored as blockchain status. Logs, in principle, can
               be recalculated on the fly as necessary.
               TX validation (by miners) will not access past logs.

             • Network as a whole does not bear the cost of logs.
             BºOnly API service nodes need to actually process, store,º
             Bºand index the logs.º
             • cost structure is kept  minimal toºprevent log spammingº.

Watch Out default gas price!!! • Extracted from stack-overflow: Q: """ETH (to USD) price has gone from ~8 to ~90 USD in 6 months ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I see that most people are still using default gas price of 2e10 wei/gas.ºShouldn't we be lowering the gas prices per TXº ºto account for this price change?º º... I intend to drop fee gas price by 75%. Will TXs still beº ºmined 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]
EIP 1559 @[https://blog.ethereum.org/2020/06/16/eth1x-1559/] [scalability][gas_price] • Problem Context: Rº• TX gas price can spike when block ussage is close to full.º • wallets trying to pay "fast" (vs waiting for TX demand/fees to go down) might end up paying ridiculous fees. (Supported by Besu and other clients). • EIP-1559 dramatically alter how gas fees are calculated. • TX fees broken into two categories: ✓ºbase feeº :Bºpredictableº based on how TX number in last block. ·ºbase fee will be burned (removed from circulation)º vs going into miner's pockets. · base fee dynamically adjust so that the overall gas usage in a block moves toward the current limit of 10 million gas. ✓ºMiner tipº: added at will by TX users in order to incentivize miners to include their TX in mined block. NOTES: • EIP-1559 does NOT reduce TX fees.
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:
BºFixed Costs:º
   └ TX gas price: 21000 gas/tx
     ┌──────────┬─────────────────┬────────┐
     │ gasprice │ total gas price │ total €│
     ├──────────┼─────────────────┼────────┤
     │  1gwei   │ 21000 x  1gwei  │ 0,0042 │
     │ 20gwei   │ 21000 x 20gwei  │ 0,0840 │
     └──────────┴─────────────────┴────────┘

BºInternal Storage Costs:º
  └ 32bytes Contract storage: 20000 gas
    ┌──────────┬─────────────────┬────────┐
    │ gasprice │ total gas price │ total €│
    ├──────────┼─────────────────┼────────┤
    │  1gwei   │ 21000 x  1gwei  │ 0,004 €│
    │ 20gwei   │ 21000 x 10gwei  │ 0,080 €│
    └──────────┴─────────────────┴────────┘
  └ Total TX cost for 64 bytes  (32bytes from debitor to creditor account)
    ┌──────────┬─────────┐
    │ gasprice │ total € │
    ├──────────┼─────────┤
    │  1gwei   │ 0,0122  │ 0,0042 (TX fix cost) + 2 x 0,0040 (32bytes Contract storage)
    │ 20gwei   │ 0,2440  │
    └──────────┴─────────┘

BºLOGS-COST:º
  └ ┌───────┬───────┬────────┬────────────┬────────────────────────────────────┐
    │size in│ num.of│ gas    │total       │  total €                           │
    │  bytes│ topics│ price  │gas price   │  (200€/eth)                        │
    ├───────┼───────┼────────┼────────────┼────────────────────────────────────┤
    │       │       │        │            │  LOG Cost   TX Cost                │
    │       │       │        │            │ ┌───────┐   ┌────┐                 │
    │  1024 │   3   │ 1gwei  │9692 x 1gwei│ 0,0019384 + 0,0042 € = 0.0061384 € │
    │   512 │   3   │ 1gwei  │5596 x 1gwei│ 0,0011192 + 0,0042 € = 0.0053192 € │
    │   256 │   1   │ 1gwei  │2798 x 1gwei│ 0,0005596 + 0,0042 € = 0.0047596 € │
    │   128 │   0   │ 1gwei  │1399 x 1gwei│ 0,0002798 + 0,0042 € = 0.0044798 € │
    ├───────┼───────┼────────┼────────────┼────────────────────────────────────┤
    │       │       │ 20gwei │9692 x20gwei│ 0,0387680 + 0,0840 € = 0.1227680 € │
    │   512 │   3   │ 20gwei │5596 x20gwei│ 0,0223840 + 0,0840 € = 0.1063840 € │
    │   256 │   1   │ 20gwei │2798 x20gwei│ 0,0111920 + 0,0840 € = 0.0951920 € │
    │   128 │   0   │ 20gwei │1399 x20gwei│ 0,0055960 + 0,0840 € = 0.0895960 € │
    └───────┴───────┴────────┴────────────┴────────────────────────────────────┘
                              └┬─┘
                               └─────────────────────────────────────────────────────────┐
     NEW LOG GAS          LOG BYTES GAS         TOPIC ("INDEX")GAS                   TOTAL GAS
    ┌───────────┐   ┌─────────────────────┐   ┌─────────────────┐                       ┌┴─┐
    (375 gas/LOG) + (8 gas/byte x 1024byte) + (375 gas/topic * 3) = 375 + 8192 + 1125 = 9692
    (375 gas/LOG) + (8 gas/byte x  512byte) + (375 gas/topic * 3) = 375 + 4096 + 1125 = 5596
    (375 gas/LOG) + (8 gas/byte x  512byte) + (375 gas/topic * 1) = 375 + 2048 +  375 = 2798
    (375 gas/LOG) + (8 gas/byte x  128byte) + (375 gas/topic * 0) = 375 + 1024        = 1399
                     ^^^^^^^^^^
                   ☞ This means 256 gas for 32bytes, version 20.000 gas for 32 bytes
                     in internal storage. Bº78.125 times cheaper per byte !!º
                                          Rº FIX TX cost not included       º
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)
EIP-2535 Diamons
@[https://eips.ethereum.org/EIPS/eip-2535]
Bº#######################################
Bº# About EIP-170 24K Max Contract Size #
Bº#######################################
@[https://ethereum-magicians.org/t/removing-or-increasing-the-contract-size-limit/3045]
 (See original link for -very- detailed info)
- 24K max. size is used to prevent denial-of-service attacks.
  ( O(n) for disk-read resources, code-preprocessing, Merkle proof data )

BºNote:º Private chains allow to tune max.contract size in consortium / private networks
         but the EIP-2535 is compatible with MainNet and provide other features to upgrade
         contracts (or a subset of functions "inside" the contract) through proxies.

º#######################################################º
º# Possible Solutions changing Ethereum Implementation #º
º#######################################################º
  - Increase contract size limit.
  - Increase cost of relevant opcodes (CALL, ...)
  - Allow infinite contract size by Implementing paging of contract code
    (suggested by @SergioDemianLerner) and "paying" for extra pages:
    - first page loaded for free 
    - jumping into another page pays a fee (500 gas) to fetch 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. ( moderate difficulty change but makes a lot of sense IMO)
    - In detail:
      - ethereum account   (array in state trie)
        ----------------
         nonce
         balance
         storageRoot     
         codeHash        New proposed additionº
        ºcodeSize     ←  · immutable value after deployment 
                         · reseted at contract destruction. 

      - CALL, DELEGATECALL, CALLCODE , ... opcodes should charge additional
        gas per extra word if contract code size greater than 24KB.
    - Rationale
      contract size limit used only to prevent exploiting fixed costs.
      Can be overcomed by making costs variable.'codeSize' helps in calculating
      call cost before reading the whole contract failing fast with Out-of-Gas.
      - Merkle proofs will be generated at a fixed cost as we won't have
        to load whole contracts from disk first. 'codeSize' should be enough
        for generating Merkle proofs of calls that will throw OOG.
    - no extra cost charged to existing contracts ( they are all under 24KB).

Bº####################################################################º
Bº# proxy pattern: (Compatible with current EIPs and implementations #º
Bº####################################################################º
  - Allows to store S.C. code in different contracts using a "dispatcher"
    contract to calls delegating calls to real contracts.
    (e.g.: ZeppelinOS's upgradability contracts, EIP-#1538) 
  - Proxy Contract == "Stay small by borrowing functions from other
                      contracts using low level opcode "delegatecall".

  Rº#############################º
  Rº# Proxy Pattern Limitations #º
  Rº#############################º
    - extra unnecessary code.
    - Proxy patterns add another attack vector.
    - Proxy patterns make contracts calls more expensive 
      ( Proxy must copy params, then make external delegate call).
    - Proxy patterns (e.g.EIP-1538) make inter-logic contract call
      (a lot) more expensive:
       external →  proxy    →  contract → contract2
       call        contract    call
    -Rºhurt readability for the end user:º
      - proxy contract code/ABI is different from real delegated code.
      Rºmost people can barely use the read/write features in etherscan,º
      Rºthey can't load a custom ABI and make web3 calls.               º
    - development is slightly more complex.
    - harder to verify actual code.
    - Loading a large contract will be fast-sequential read while loading
      multiple small ones will be slow-random read.

Bº###########################################################
Bº# EIP-2535 Diamon Standard (STANDARD FOR PROXY CONTRACTS) #
Bº###########################################################
  - COMPILER AWARE UPGRADABILITY OF CONTRACTS USING FACETS !!!!  by Nick Mudge
    Replaces "EIP-1538 Upgradeable Contracts" (also by Nick Mudge).
  - The idea is to use a proxy contract with an internal database that maps 
    each function implementation to a different contract (address).

  - STATE AND FUNCTIONS ARE KEPT TOGETHER UNDER THE SAME ETHEREUM ADDRESS.
    MAKING EASIER AND MORE FLEXIBLE TO ACCESS/MODIFY CONTRACT STORAGE.
  
  - PROVIDES A FLEXIBLE AND TRANSPARENT METHOD TO SUPPOR UPGRADEABLE DIAMONDS.

   """ ... A diamond could be structured like this:
       • The diamond has 10 facets.
       • Each facet has N functions.
       • Each facet covers a distinct area of functionality.
         (ownership, identity, NFT, ...)
       • Each facet has its own state variables declared it its own 
         Diamond Storage contract, or it shares state variables with a small 
         number of facets via one or more Diamond Storage contracts.
   """

  Bº############################º
  Bº# DIAMON STORAGE PATTERNS  #º
  Bº############################º
  @[https://medium.com/1milliondevs/solidity-storage-layout-for-proxy-contracts-and-diamonds-c4f009b6903]
  @[https://medium.com/1milliondevs/new-storage-layout-for-proxy-contracts-and-diamonds-98d01d0eadb]

  • PROBLEM CONTEXT:
    Standard Storage Layout rules for non-proxy contracts: 
    ====================================================== 
    - 1st state variable stored at position 0,
      2nd state variable stored at position 1, 
                \_-----------_/ 
      ...
      this also include arrays/maps "pointers" (vs arrays/map values)
    - Dynamic arrays/maps store values at positions based on
      hash (array|map pointer-storage-position, array-index|map-key).
    
    When using proxiesºCOLLISIONS WILL ARISEº since (at compilation time)
    Solidity is not aware of "peer" contracts implementing the proxy.
  
    ┌───────────────────── PROPOSED SOLUTIONS/STORAGE-PATTERNS ***BEFORE DIAMON STANDARD**** ───────────────────────────────────────────────────┐
    | UNSTRUCTURED STORAGE, using assembly,           | INHERITED STORAGE:                         | ETERNAL STORAGE PATTERN:                   |
    ├─────────────────────────────────────────────────┼────────────────────────────────────────────┼────────────────────────────────────────────|
    |                                                 |- proxy contract + facets inherit a storage |Both proxy/ies and facet/s use a general    | 
    |contract ProxyA {                                |  contract with storage variables used      |storage based on maps                       |
    |    const bytes32 STATE01_POS =                  |  ensuring no collision arise.              |contract .... {                             |
    |          = keccak256("state01");                |                                            |   mapping(bytes32 =˃ uint256  ) uIntStore; |
    |    function getState01() ...                    |                                            |   mapping(bytes32 =˃ string   ) stringStore|
    |    returns(address state01) {                   |                                            |   mapping(bytes32 =˃ address  ) addrStore; |
    |      assembly { state01 := sload(STATE01_POS) } |                                            |   ...                                      |
    |    }                                            |                                            |                                            |
    |    function setstate01(address state01) ... {   |                                            |   function (...) {                         |
    |      assembly { sstore(STATE01_POS, state01) }  |                                            |      return addressStorage["user"];        |
    |    }                                            |                                            |      addrStorage["user"] = newUser;        |
    |}                                                |                                            |}                                           |
    ├─────────────────────────────────────────────────┼────────────────────────────────────────────┼────────────────────────────────────────────{
    |DOWNSIDES:                                       |DOWNSIDES:                                  |DOWNSIDES:                                  |
    |• One getter+setter function for each storage var|• Facets need to inherit storage contracts  |• Clumsy syntax.                            |
    |• It does not work for complex types             |  that they don't use breaking the basic    |• It          works for values|arrays       |
    |  (structs, mappings, ...).                      |  "IS-A" inheritance rule in OOP.           |  it does not work  for mapping|struct vals.|
    |                                                 |• Facets become tightly coupled to specific |  (in simple/generic way).                  |
    |                                                 |  proxy contracts (Due to the "IS-A" inher.)|• proxies and facets forced to use the same |
    |                                                 |• facets CANNOT be used by other proxy      |  storage API.                              |
    |                                                 |  contracts declaring different state vars. |• Not easy to see at what state var. exist  |
    |                                                 |                                            |• More gas needed than direct access.       |
    |                                                 |                                            |                                            |
    ├─────────────────────────────────────────────────│ ────────────────────────────────────────────────────────────────────────────────────────│
    |• proxy-contract delegates on single pattern.    |• good for diamonds delegating to different facets depending on which function is called.|
    └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  
      Solidity v0.6.4+ allows to set storage slots for storage reference 
    variables from inline assembly within solidity code (bypassing 
    default Compiler default storage patterns causing conflicts among 
    proxy instances ). @[https://github.com/ethereum/solidity/releases/tag/v0.6.4]
    allowing new storage patterns for delegatecall-proxies/upgradable contracts.
  
    ┌─ DIAMOND STORAGE PATTERN : Bº NO STORAGE DOWNSIDES !!!º ───────────────────────────────────────────
    │
    │ PRE-SETUP: Create Storage Contract/s: 
    │ → Create a "Diamond Storage contract" for each storage "interface implementation".                
    │   → Inside it, create struct/s with suitable state variables for the interface implementation.
    │     → Choose a position in storage for the struct/s.
    │       → Write a function inisde the storage contract creating and returning the storage pointer.
    │ ┌ e.g: ───────────────────────────────────────────────────────┐
    │ │ contract MyIdentityStorageContract {                        ← Create one for each storage pattern
    │ │   struct MyStorage {                                        ← struct 
    │ │     uint aVar;                                              │
    │ │     bytes myBytes;                                          │
    │ │     mapping(uint =˃ bytes32) myMap;                         │
    │ │   }                                                         │
    │ │                                                             │
    │ │   function myStorage()                                      ← Public func. used by proxies/facets
    │ │   internal                                                  │
    │ │   pure                                                      │
    │ │   returns(MyStorage storage ms) {                           │
    │ │     // ms_slot = keccak256("com.mycompany.my.storage")      ←·· Namespaces come for free!!!
    │ │     assembly {ms_slot := 0xabcd55b489adb030b...d09c4154cf0} │
    │ │   }                                                         │
    │ │ }                                                           │
    │ └─────────────────────────────────────────────────────────────┘
    │ For each contract/proxy/facet using the storage contract:
    │   → inherit storage contract 
    │     → call the function returning the storage pointer.
    │ 
    │ ┌─ e.g. Storage "consumer" ─────────────────────────┐
    │ │ contract MyContract is ...  MyStorageContract {   │
    │ │    constanct MyStorage storage MS01 = myStorage();← Instantiate MyStorage
    │ │    function ...(...) external {                   │
    │ │      MS01.myMap[selector] = myData;               ← Write to MyStorage.
    │ │      MS01.aVar = uint(myData);                    │
    │ │      ...                                          │
    │ │      bytes32 data = MS01.myMap[selector];         ← Read from MyStorage.
    │ │      ...                                          │
    │ │    }                                              │
    │ │ }                                                 │
    │ └───────────────────────────────────────────────────┘
    │ 
    │ 
    └──────────────────────────────────────────────────────────────────────────────────────────

    ┌─ Diamond Implementation S.C. ───────────────────────────┐  
    │                                                         │
    │ mapping (bytes4 ←·········································· function 'ABI' 
    │          =˃ address  ←····································· contract instance
    │ ) internal FACETS_DDBB;                                 │   implementing it */ 
    │  e.g.:                                                  │
    │  e2532512(func1)  =˃ 0x0....contract "Facet" A          ←─┐               ┌──────┐
    │  ───────────────     ─────────────────────────          │ ├───────────────│facetA│
    │  253e253A(func2)  =˃ 0x0....contract "Facet" A          ←─┘               │S.C.  │
    │  ───────────────     ─────────────────────────          │                 └──────┘
    │  FA539B19(func3)  =˃ 0x0....contract "Facet" B          ←─┐                  │
    │  ───────────────     ─────────────────────────          │ │      ┌──────┐    │
    │  D38A5B17(func4)  =˃ 0x0....contract "Facet" B          │ ├──────│facetB│    │
    │  ───────────────     ─────────────────────────          │ │      │S.C.  │    │
    │  16D253AB(func5)  =˃ 0x0....contract "Facet" B          ←─┘      └──────┘    │
    │  ───────────────     ─────────────────────────          │           │        │
    │  ...     (func6)  =˃ 0x0....contract "Facet" C          ←─┐ ┌──────┐│        │
    │  ───────────────     ─────────────────────────          │ ├─│facetC││        │
    │  ...     (func7)  =˃ 0x0....contract "Facet" C          ←─┘ │S.C.  ││        │
    │                      └──────────┬────────────┘          │   └──────┘│        │
    │                      facets are contract/s that         │    │      │        │
    │                      diamond borrows functions          │    │      │        │
    │                      from.                              │    │      │        │
    │ ┌────────────────────────┐                              │    │      │        │
    │ │struct DiamondStorage1 {│   ←── facetC ─────────────────────┤      │        │
    │ │  ...                   │                              │    │      │        │
    │ │}                       │                              │    │      │        │
    │ └────────────────────────┘                              │    │      │        │
    ╞═════════════════════════════════════════════════════════╡    │      │        │
    │ "diamondCut(...)": add/replace/remove/facets⅋functions. │    │      │        │
    │                                                         │    │      │        │
    │ "loupe": introspection info. about facets⅋functions.    │    │      │        │
    │                                                         │    │      │        │
    └─────────────────────────────────────────────────────────┘    │      │        │
    ┌─ S.C. Storage2 ─────────────────────────────────────────┐    │      │        │
    │ ┌────────────────────────┐                              │    │      │        │
    │ │struct DiamondStorage2 {│   ←── facetC ─────────────────────┘      │        │
    │ │  ...                   │   ←── facetB ────────────────────────────┤        │
    │ │}                       │                              │           │        │
    │ └────────────────────────┘                              │           │        │
    └─────────────────────────────────────────────────────────┘           │        │
    ┌─ S.C. Storage3 ─────────────────────────────────────────┐           │        │
    │ ┌────────────────────────┐                              │           │        │
    │ │struct DiamondStorage2 {│   ←── facetB ────────────────────────────┘        │
    │ │  ...                   │   ←───facetA ─────────────────────────────────────┘
    │ │}                       │                              │
    │ └────────────────────────┘                              │
    └─────────────────────────────────────────────────────────┘  
  
Bº##################º
Bº# Diamon Tooling #º
Bº##################º
• MainNet diamon "loupe" inspector
@[https://louper.dev/]
• Joey Zacherl@VolleyFire (liquidity provider for decentralized exchanges), 
  released "Diamond Setter", (Python) tool to manage diamonds.
  @[https://github.com/lampshade9909/DiamondSetter]
    23 stars @ 2021-11, last commit: 2020-06-11, 60 package dependencies.
    PRE-SETUP)
    - User python standard virtualenv mechanism to configure project.
    USSAGE)
    → Copy ABI JSON files to "Contracts/"
      (make sure filename matches contract name in config)
      → provide contract addresses in "diamondSetter.config" *1
        (template "diamondSetter_template.config" can be used) 
        → $º$ python diamondSetter.py set º
          App will automatically determine what needs upgraded/removed
          by calling the proper Diamond Standard functions.  
          diamondCutDict_removes = {}
          diamondCutDict_updates = {'0xd3758...': ['d22fd5fc', 'ba802cef'], 
                                    '0xc630a...': ['a39fac12', 'c6ee701e', ...]}
          diamondCutDict_merged  = {'0xd3758...': ['d22fd5fc', ... ],
                                    '0xc630a...': ['a39fac12', 'c6ee701e', ...]}
                                                  └──────────────┬────────────┘
                                                  function selectors affected in proxy diamond
    
        → $º$ python diamondSetter.py hash diamond.storage.tutorial.properties º
            Next assembly code gets added to your solidity smart contract:
    
          assembly { ds_slot := 0x8009ef9e316d149758ddd03fd4cb6dd67f0acee3d8cdf1372cf6f2ac6d689dbd }
                                └───────────────────────────────┬────────────────────────────────┘
                                    == keccak256("diamond.storage.tutorial.properties")
    
          Use same 'ds_slot' across multiple contracts to share storage or unique one to prevent
          sharing.
 
  *1 Config example: 

     | [ACCOUNT]
     | publicAddress = ...
     | privateKey = ...
     | gasPrice_gwei = 20
     | 
     | [NODE]
     | url = http://...
     | 
     | [CONTRACT_PROXY]
     | filename = tutorial_proxy
     | address = 0xfb1495fb3adca65a1c3374f206971891d3137ff9
     | 
     | [CONTRACTS_LOGIC]
     | tutorial_logic_a    = 0xd37589ee0c581ef58efab0d2adb08d08b373125f
     | tutorial_properties = 0xc630aae56ac54f52ee7fb757bf6b23f86a8aacea


• Ronan Sandford (wighawag),  (ERC-1155 author), announced
  WiP support for deploying/cutting diamonds in "buidler-deploy"
  a tool to deploy contracts to any network, keeping track
  of them and replicating the same environment for testing.

• Nayms is using diamonds in production. See blog post:
  " Upgradeable smart contracts using the Diamond Standard"
  - reddit announment:
  @[https://www.reddit.com/r/ethereum/comments/hu3gq1/erc1155_multi_token_standard_updated_to_mention/]

• Issue open in OpenZepelling to use diamon standard:
@[https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2537]
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

EWASM
EWASM
@[https://ewasm.readthedocs.io/en/mkdocs/]
Ethereum WebAssembly is a proposed redesign of the Ethereum smart
contract execution layer using a deterministic subset of WebAssembly.
The use of WebAssembly as a format for smart contracts gains a
variety of benefits, a few of which are listed below:
- Near-native execution speed for smart contracts
- The possibility to develop smart contracts in many traditional
  programming languages, such as C, C++, and Rust
- Access to a vast developer community and the toolchain surrounding WebAssembly
Solidity
What's New
BºSolidity 0.8 Breaking changesº
@[https://github.com/ethereum/solidity/blob/develop/docs/080-breaking-changes.rst]

  - Silent Changes of the Semantics
    - Arithmetic operations revert on underflow and overflow.
      You can use ºunchecked { ... }º to go back to previous wrapping behaviour.
      (better readability of code withslight increase of gas costs)

  Bº- ABI coder v2 is activated by default.º:
      (pragma experimental ABIEncoderV2" not-needed/redundant)
      - supports for more types and better sanity checks on inputs.
      -Rºsome fun. calls are more expensiveº

    - internal checks (failing assertions,div-by-zero, overflow,...) translate to revert (vs invalid) opcode.
      Bºsaving gas on errorsº while  allowing static analysis tools to distinguish
      them from  invalid-input-reverts (failing "require").

    - If a byte array in storage is accessed whose length is encoded incorrectly, a panic is caused.
      A contract cannot get into this situation unless inline assembly is used to modify the raw representation of storage byte arrays.

    - constants 'variables' values used in array length expressions as intermediate expressions properly rounded.
      (previously, arbitrary precision used in all branches of the evaluation tree).

    - "byte" removed in favor of "bytes1".

  - New Restrictions
    - removed ambiguous syntax "here and there".
    - Address literals have the type "address" (vs "address payable"). Use explicit conversion. Ex:
      payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF).

    - explicit type conversions only allowed forºat mostºone change in sign, width or type-category.
     ºmultiple changes will require multiple conversionsº. Ex: uint16(int8) →  uint16(uint8(int8))
                                                                               ^lenght^sign

    - call options can only be given once: c.f{gas: 10000}{value: 1}() →  c.f{gas: 10000, value: 1}()

    - ºenumº max length 256 members. (allows to assume uint8)

    - global vars 'tx.origin' and 'msg.sender' have type "address"` (vs payable address)
      Ex: msg.sender.transfer(x) → payable(msg.sender).transfer(x)

  - See source to check How update old code

Bº0.7.0º
  https://github.com/ethereum/solidity/blob/develop/docs/070-breaking-changes.rst
  - Silent Changes of the Semantics
    - Exponentiation and shifts of literals by non-literals (e.g. 1 ˂˂ x or 2 ** x)
      will always use either the type uint256 or int256

    - Ether and gas is now specified using a new syntax:
      x.f{gas: 10000, value: 2 ether}(arg1, arg2) vs x.f.gas(10000).value(2 ether)(arg1, arg2)

    -Rºglobal variable ºnowº is deprecatedº
     Bºblock.timestamp should be used insteadº.

    - NatSpec comments on variables only allowed for public state variables

  Bº- Unicode string literals supported now.  unicode"Hello 😃"º

    - state mutability of functions can now be restricted during inheritance                        [qa]
      with "pure" and "view".

    - structs and arrays containing mapping can only be used in storage.
      (Previously, mapping members Rºsilently skipped in memoryº)

    - Assignments to structs or arrays in storage does not work if they contain mappings.
      (Previously, mapping members Rºsilently skipped during the copy operationº)

    - Visibility (public/external) not needed in constructors anymore.
    Bº To prevent a contract from being created, mark it as ºabstractº.

    - using A for B must be repeated in all derived contracts of B.
BºSolidity 0.6 Breaking changesº
  https://github.com/ethereum/solidity/blob/develop/docs/060-breaking-changes.rst

  - Breaking changes:
    - Explicitness Requirements:
      - only functions marked as virtual can be overridden.
      - "override" must be used in implementing children.

    - Member-access to ".length" in arrays is always read-only (including storage ones).
      No possible to resize storage arrays by assigning a new value to their length.
      Use "push()/pop()" or "push(value)" instead.
      push(value) for dynamic storage arrays returns nothing (new length previously)
      This prevents storage collisions of gigantic storage arrays.

    - "abstract" keyword can be used to mark contracts as abstract.
      - This avoids creating such contracts with "new" operator.
      - not possible to generate bytecode for them during compilation.

    - Libraries have to implement all their functions, not only the internal ones.

    - unnamed "fallback function" split up into:
      - fallback function marked with "fallback" keyword.
        - called when no other function matches
        - can be payable or not.
      - receive  function marked with "receive " keyword. implicitly "payable".
        - called whenever the call data is empty (with/without ether received).

  - New Features
    - try/catch statement allows to react on failed external calls.               [qa][error-handling]
    - "struct" and "enum" types can be declared at file level.
    - Array slices can be used for calldata arrays.
      e.g.: low-level way to decode function call payload
            abi.decode(msg.dataº[4:]º, (uint, uint))" [TODO]
    - Natspec supports multiple return parameters in developer documentation.
    - "address" → "address payable" conversion thanks to: payable(myaddress)
    - compiler now appends the `IPFS ˂https://ipfs.io/˃`_ hash of the metadata file to the
      end of the bytecode by default (previously swarn hash by default)

@[https://blog.ethereum.org/2020/01/29/solidity-0.6-try-catch/]
solc (Solidity Compiler)
• svm: Solidity compiler Version Manager, similar to Node nvm,..
@[https://github.com/web3j/svm]
$º$ svm install 0.6.2 º ← install|uninstall|deactivate
$º$ svm use     0.6.2 º   use|current
                          ls|ls-remote
                          alias|unalias
•ºCOMPILING:º
@[https://docs.soliditylang.org/en/latest/using-the-compiler.html]
$ solc  \
  --base-path ...              ← default: ./
  --include-path ...           ← default: ./
  github.com/.../lib1/=./lib1/ ← (Opt) (src)input path redirect
  -o outputDirectory \
  --bin --ast-compact-json \

  --optimize                 ← Don't forget before deploying
                               opcode is executed ~200 times. 
                          --optimize-runs=$N
                           ┌───────────────┘
                           N=1:    deploy -expensive/exec. +expensive
                           N=1000: deploy +expensive/exec. -expensive
                           Affected tunning:
                           • size of binary search in 'dispatch'
                           • storage of constants (strings,..)
  --asm sourceFile.sol

•ºLINKINGº
  • Replace bytecode placeholders (__$...34 chars...$__) with
    with actual library addresses, where the 34 chars is the 
    keccak256("fully-qualified-library-name") 
    (bytecode will end with some extra metadata:
     // placeholder -˃ fq-library-name as a hint )

  $ export LIB_MATH="0x...hex-address-of-deployed-lib..."
  $ export LIB_HEAP="0x...hex-address-of-deployed-lib..."
  $ solc --libraries \
    "file.sol:Math=${LIB_MATH} file.sol:Heap=${LIB_HEAP}"
    ...
• Using JSON as (STDIN) input: ºRECOMENDED FOR AUTOMATED BUILDSº
  $ solc --standard-json ... ← return JSON-output on  STDOUT.
                               Always success. Errors are 
                               reported through JSON-output
  (go to offical doc for more details)

• EVM Version --evm-version  (settings.evmVersion JSON) affects
  compiler output in different ways:

  ────────────────────────────────────────────────────────────
  homestead  · (oldest version)
  ────────────────────────────────────────────────────────────
  tangerine  · Gas cost for access to other accounts 
    Whistle    increased, relevant for gas estimation and the 
               optimizer.
             · All gas sent by default for external calls, 
               previously a certain amount had to be retained.
  ────────────────────────────────────────────────────────────
  spurious   · Gas cost for the exp opcode increased, 
    Dragon     relevant for gas estimation and the optimizer.
  ────────────────────────────────────────────────────────────
  byzantium  · Opcodes returndatacopy, returndatasize and 
               staticcall are available in assembly.
             · The staticcall opcode is used when calling 
               non-library view or pure functions, which 
               prevents the functions from modifying state at 
               the EVM level, i.e., even applies when you use 
               invalid type conversions.
             · It is possible to access dynamic data returned 
               from function calls.
  ────────────────────────────────────────────────────────────
  constan-   · Opcodes create2`, extcodehash, shl, shr and 
   tinople     sar are available in assembly.
             · Shifting operators use shifting opcodes and 
               thus need less gas.
  ────────────────────────────────────────────────────────────
  petersburg · compiler behaves the same way as with constantinople.
  ────────────────────────────────────────────────────────────
  istanbul   · Opcodes chainid and selfbalance are available in assembly.
  ────────────────────────────────────────────────────────────
  berlin     · Gas costs for SLOAD, *CALL, BALANCE, EXT* and 
               SELFDESTRUCT increased. The compiler assumes cold 
               gas costs for such operations. This is relevant 
               for gas estimation and the optimizer.
  ────────────────────────────────────────────────────────────
  london     · (default as of 2022-01)
             · The block’s base fee (EIP-3198 and EIP-1559) 
               can be accessed via the global block.basefee or 
               basefee() in inline assembly.
  ────────────────────────────────────────────────────────────

• JSON-INPUT:
  {
    "language": "Solidity",  ← "Solidity" | "Yul".
    "sources": {
      "myFile.sol": {
        "keccak256": "0x123...",  ← Optional: used to verify retrieved content
        "urls": [...]             ← Ordered list of bzzr://, ipfs://, FileSystem paths
      },                            (only FS allowed to commandline interface)
      "destructible": {
        "keccak256": "0x234...",  ← Optional
        "content": "... "         ← Inline contract source code
      }
    },
    {                      ←  Optional "settings":
      "stopAfter": "parsing",
      "remappings": [ ":g=/dir" ],
      "optimizer": {...}   ← active?, runs over opcodes,
        "details": {...},  ← peephole,inliner,jumpdestRemover,orderLiterals,
                             deduplicate,cse,constantOptimizer,yul/yulDetails
      "evmVersion": "byzantium",
      "viaIR": true,  ← highly EXPERIMENTAL. compile through Yul 
      "debug": {
        "revertStrings": "default",   ←  "strip"  : removes all keeping side-effects
                                         "debug"  : injects compiler-generated reverts.
                                                    (ABI encoders V1 and V2)
                                         "verboseDebug":  appends further information 
        "debugInfo": ["location", "snippet"] // extra debug info to include in ASM/YUL
      },
      "metadata": {
        "useLiteralContent": true,
        "bytecodeHash": "ipfs"
      },
      "libraries": {  ← needed for linkin libraries.
        "myFile.sol": { "MyLib": "0x123123..." }
      },                   Enable abi output for all contracts. Compiler output 
      "outputSelection": { types include:
        "*": {             abi, ast, devdoc, userdoc, metadata, ir/irOptimized(Yul),
          "*": [ "abi" ] ← storageLayout(Slots/offsets/types of contract's vars),
        }                   evm.assembly, evm.bytecode.*, evm.methodIdentifiers
    }                      ,evm.gasEstimates, ewasm.wast, ewasm.wasm
    "modelChecker":{...} ← experimental/subject to changes (Formal Probes)
  }

• JSON-OUTPUT
  {
    "errors": [ { ... } ],
    "sources":   {...} // file-level outputs.
    "contracts": {...} // detailed contract-level output
  }

Troubleshooting • CONTEXT: Next code compiles "OK" for A and B: 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; } • Problem: Now we add constructor to parent A contract. An B output is empty. • SOLUTION: B does NOT implements all mehtods of declared interfaces or base clases. solc compiler consider the class abstract and does not generate any bin. B will need to provide parent A constructor with a parameter: contract B is A { uint8 public b1; constructor(address _a) A(_a) { ... } } Src.upgrade @[https://docs.soliditylang.org/en/latest/using-the-compiler.html#solidity-upgrade] • solidity-upgrade semi-automatically upgrade contract source code
Source Code Verification • PRE-SETUP) Anotate the solc compiler version used as well as compiler flags @[#solc_summary] • STEP 1) Go to some online service like: @[https://etherscan.io/verifyContract] • Source code verification works by compiling the code you claim is the source code and comparing the resulting bytecode (bitwise) to what is deployed. If it matches, SUCCESS. • BEST PATTERNS: @[https://ethereum.stackexchange.com/questions/74785/publish-and-verify-the-source-contract-code-in-ethscan-i-tried-it-but-it-keeps/74796] • """ ...contract has ^ in pragma, so no one can be sure what compiler was used. Its presence is a sign that the code hasn't received an appropriate critical review. ... If you can inspect the machine that compiled it, and the compiler (solc, truffle, remix) you might be able to piece together what version was used. ..." Decompiling mainnet Contracts @[https://www.contract-library.com/] - Decompiles most smart contracts deployed on the mainnet to a high level representation. Show also source code when available @[https://contract-library.com/contracts/Ethereum/42A1CA0A79A9E7D83AEE9012D21920B02F9FC2C6]
Solidity 101
(Initial version from @[https://learnxinyminutes.com/docs/solidity/] 
 with "lot of extras")
●º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.
    (See "events" topic for related info)

  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 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, ...).

● NATSPEC COMMENTS
  /// @title Contract title
  /// @author Author name
  contract ... {
  
    /// @notice information about what function does;
    /// @dev Function documentation for developer
    /// @param someParam Some description of what the param does
    /// @return Description of the return value
    function ... {

● import "filename";                         ºIMPORTSº
  import * as symbolName from "filename";     NodeJS tooling (truffle,...) will also 
  import {symbol1 as alias, symbol2}          import from "node_modules/" 
         from ""filename"";
  import ""filename"" as symbolName;
  

● FALLBACK FUNCTION: (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);
  };

● DATA TYPES / STORAGE:
  NOTE: In Solidity/Ethereum, contract data structures like maps/arrays can and 
        ussually are automatically  persisted to permanent storage (on each
        potential node in the 1000's of nodes network!!!). Temporal storage 
        in memory/calldata must be indicated explicetely. 
  • no doubles or floats (Risky in the Accountancy World)
  • Minimal support for strings, it use is discouraged.
  uint public constant z        All non-explicitely assigned values return zero.
                              RºWARNº: 'private' members are still visible/readable 
                                       to anyone except the Solidity-compiler.
  uint public constant a = 8; ← 32 bytes (256bits), alt. uint256
                                or (u)int(8,16,24,...,248,256)
                                internal visibility by default.  
                                'public' automatically creates getter (NOT setter)
  uint immutable x;           ← immutable: Init@constructor, constant from there on.
  uint256 c = a + b;
  assert(c ˃= a);             ← Check overflow. TIPO: Use Zeppelin's SafeMath lib
  bool b = true;              ← boolean, alt(type inferred): var b = true; 
  address payable owner;      ← 20 byte Ethereum addresses (arithmetic not allowed)
                                Mark as 'payable' to allow sending ethers.
  this;                       ← address of current contract
                                WARN: this.func1() call func. externally.
                                           func1() call func. internally (faster)
  owner.transfer("balance");  ← reverts on failure
  if (owner.send) {}          ← low-level send allows to capture failure..
                                Make sure to update/decrease internal contract balances
                                BEFORE attempting a send, to avoid recursive drains.
  owner.balance;              ← check balance for owner
  byte1 a;                    ← byte2, byte3, ... bytes32

  bytes m;                    ←  same as byte[] array (but packed tightly in calldata)
                                 More expensive than byte1-byte32, so use those when possible

  string n = "hello";         ← stored in UTF8, internally same as bytes, BUT does 
                                NOT allow length/index/push access (202?)
                                string utility functions  could be added 
                                prefer bytes32 hash of string when possible
                                · use bytes(myString).length / bytes(myString)[7] = 'x' to
                                  access the low-byte-representation of myString
                              RºWARN:º string[] arrays not allowed.

  var f = someFunction;       ← assign function to variable.
      f(22);                    ← call func.

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

  enum State {                ←ºENUMSº
     Created,
     Locked,
     Inactive 
  };
  State public s0 = State.Created;
  state = State.Created;
  uint8  i_8_0 = uint8(State.Created);  ← enums can be explicitly converted to ints
  uint16 i16_0 = uint16(State.Created); ← enums can be explicitly converted to ints
  State s2 = State(i_8_0)               ← uintXX → enum using enum constructor
                                          Will raise an assert exception if
                                          u1 is outside the State bounds.

● DATA LOCATIONS: 
  • Memory  : intermediate operations.
  • calldata: input data.
  • storage : internal state.

● Basic operators: Comparisons, bit operators and arithmetic.
  WARN: ^  XOR (use '**' for exponentiation)

● Predefined constants (at Tx runtime)
  msg.sender; ← address of sender (or contract calling our contract)
  msg.value;  ← weis provided to this contract. function should be "payable"
  msg.data;   ← bytes, complete call data, used for example for multi-signatures
                in a single (expensive) transaction.
  msg.gas;    ← remaining gas
  
  tx.origin;  ← signer of TX sent to blockchain
  tx.gasprice;← gas price of the transaction
  
  
  block.timestamp ← aprox UNIX-current time  (alias: 'now') 
                    WARN: Can be manipulated by miners
  block.number;
  block.difficulty;
  block.blockhash(1); ← bytes32, only works for most recent 256 blocks
  block.gasLimit();
  
● "Common" pattern: remove function removing storage/code from 
  current/future blocks (helps thin clients). (Alternatively, de-activate)
  function remove() {
    if(msg.sender == creator) { ← creator registered in constructor
      selfdestruct(creator); 
    }
  }


● Setting max-gas allowed for calls to 
  external non-trusted Contracts:
  NonTrustedContract.someMethod (...);  ← WARN!: External contract can
                                                 potentially waste all gas.
  NonTrustedContract                    ← Protect. 
   .someMethodº{ gas:gasleft() }º(...);   TODO:(0) Detail protection.


Currency Units ● Currency units: (Useful in public network, not that much in consortium ones) wei : basic unit in solidity code, APIs, ... gwei = 1^9 weis , ºgas pricesº. Ex. web3j default gas price is 22 gwei alias: shannon|nanoether|nano szabo = 1^3 gweis, alias: |microether|micro finney = 10^6 gweis, micropayments, alias: |milliether|milli ether = 1^9 gweis, main unit kether = 1^3 ethers, alias: (grand|einstein) mether = 1^6 ethers gether = 1^9 ethers tether = 1^12 ethers ● Time units: second : unit-of-time minutes days
Data Structures 101 ●ºSTRUCTSº struct Bank { ← DECLARE STRUCT address owner; ← all vars are "zero-value" by default. uint balance; except mappings } Bank b = Bank({ owner: msg.sender, balance: 5 }); b.balance = 5; delete b; ●ºARRAYSº bytes32[5] fixedArray1; ← STATIC/FIXED-SIZE ARRAY DECLARATION fixedArray[0] = 1; ← Intialization. fixedArray[1] = 2; fixedArray.push(3);← RºError. Not allowed for fixed size arrayº bytes32[] memory ← dynamic array declaration/initialization dnyArray1 = bytes32[](3); ← Dynamics arrays in memory are NOT really dynamics. An given size must be defined at initialization to avoid memory overflows. The only difference with fixed size array is that they can be used as parameters in functions receiving an array of undefined size. dynArray1[0] = ...; ← By default. values is "Zero". dynArray1[1] = ...; dynArray1.length uint[] storage ← Dynamic Size Array declaration dynArray2 = uint[] dynArray1.length = 1 ← Fails for in-memory dyn arrays dynArray2.length = 5 ← OK for in-storage dyn array dynArray1.push(1) ← Fails? (TODO) dynArray2.push(1) ← OK, returns new array length uint newLength = dynArray1.push(...); uint x[][5]; ← 2-dimensional Dyn.array of uint[5] ... var storage x = uint[][5] ← Fixed-(5)size-array of dynamic-uint-arrays (var for type inference) x[2][1] ← second uint in third dyn-array funcX( [uint(1), 2, 3] ); ← Array Literal expression (not assigned to vars.) └─────────────┘ - type : memory array of fixed length. - base type: common type of array elements. Array Limitations:º · arrays of arrays not (YET 202?) 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 leading to unpredictable gas costs if a contract itself has to search through those gaps. Can be fixed (See @[#solidity_storage_patterns] for ( uint idx=0; ← ºWALK OVER ARRAYSº i˂arr.length; idx++) { require(array3[i] ...); } ┌────────┬─────────────────────┬───────────────┬──────────────────────┬──────────────────┐ │ │ Admited type │ Creation │ Resize │ Delete │ ├────────┼─────────────────────┼───────────────┼──────────────────────┼──────────────────┤ │Storage │ ºanyº │ (just declare │- set/reassign .length│ delete myArray; │ │Arrays │ │ it) │- 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) │ │ └────────┴─────────────────────┴───────────────┴──────────────────────┴──────────────────┘ •ºMAPS (DICTIONARIES / HASH-TABLEs)º key-type: almost any type except mapping, dynamic array, contract,enum,struct mapping public (string =˃ uint) map1; ← Keys can not be iterated. Manual support needed More info: @[#solidity_storage_patterns] • Care must put to not leave orphaned data in the state database, specially in self-destruction Code must manually clean mappings by DELETING EACH KEY. map1["charles"] = 1; ← add/modify key. delete balances["charles"]; ← contract.map1("charles") ← 'public' allows 3rd contracts read (not write) it. map1["non_existing_key"] ← Returns 0. All non-set values are set to zero mapping ( ← Nested mappings address =˃ mapping ( address =˃ uint)) public custodians; • ºMAP WALK-OVERº - PROBLEM: Mappings are virtually initialized: -ºevery possible key exists mapped to zero-byte-reprº - keys are NOT stored in the map. - values are stored at the state-memory address == sha3(key) - Solution: @[#solidity_storage_patterns]
Retrieve events quickly
- Imagine theºcommon problemº:
  - A given contract emits a given event sparsely, with
    an average of 1 event each 10.000 blocks.
  - We want to retrieve all events.
  - By default the client needs to query from block-zero
    to latest block. This can means query-times of more than
    a minute even in dedicated hardware.
 ºSOLUTIONº:
  - Save as contract state the block when an event has been
    emitted.
    The on the event add the information for the previous
    block where such event was emitted.
  - On client code run backward from last-to-first even
    using the state to retrieve the latest block, and then
    the event information to "jump" to the previous block.

ºSOLIDITY:º
contract MyContract {
   uint GºpreviousBlockº= 0;

   event MyEvent01(address indexed A,..., uint GºpreviousBlockº);
   //                                            └──────┬─────┘
   //               pointer to last event block helpsi ←┘
   //               external clients(etherjs,web3j,...)
   //               search quickly.

   function ....(...) ... {
     emit REC(msg.sender,... , GºpreviousBlockº);
     lastBlockDREC = block.number;
   }
}

ºCLIENT-SIDE :º
(javascript pseudo-code example)
   /*
    * GºRun events backward, from last to firstº
    */
   async function getFilters(LAST_BLOCK) {
     var LAST_BLOCK = await CONTRACT.GºpreviousBlockº()
     while ( LAST_BLOCK ˃ 0 ) {
       value = await CONTRACT.getFilter(/*1st block=*/LAST_BLOCK, LAST_BLOCK)
       console.log(value.toString());
        LAST_BLOCK = value.previousBlock
     }
   }
   getFilters(LAST_BLOCK)
}
Flattening code
@[https://stackoverflow.com/questions/50137954/verify-smart-contract-code-deployed-with-truffle]
- https://github.com/BlockCatIO/solidity-flattener
- https://github.com/nomiclabs/buidler
- https://github.com/nomiclabs/truffle-flattener
- https://github.com/RyuuGan/sol-merger
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 be used as keys for mappings
- Concatenating strings str01, str02, str03, ...:
  string memory result = string(abi.encodePacked(str01, str02, str03, ...);
- uint256 ("Big Number") to string:
  function uint2str(uint256 _i) public pure returns (string memory _uintAsString) {
     if (_i == 0) { return "0"; }
     uint256 strLen;
     uint256 j;
     for (j = _i; j != 0; j /= 10 ) { strLen++; }
     bytes memory bstr = new bytes(strLen);
     uint256 strPosition = strLen;
     for (j = _i; j != 0; j /= 10 ) {
       strPosition -= 1;
       bstr[strPosition] = bytes1 ( uint8 ( 48 + ( j % 10 ) ) );
     }
     return string(bstr);
   }

ºComparing strings:º
   sha3(      "string1" ) == sha3("string2")  ← sha3("...") translates to sha3(bytes("..."))
   ^^^^
   remember: sha3 is an alias for keccak256
 RºWARNº:  Ethereum SHA3 != SHA3-NIST standard
   SHA3 Solidity  5f16f4c7f149ac4f9510d9cf8cf384038ad348b3bcdc01915f95de12df9d1b02
   Keccak-256     5f16f4c7f149ac4f9510d9cf8cf384038ad348b3bcdc01915f95de12df9d1b02
   SHA3-256-NIST  7f5979fb78f082e8b1c676635db8795c4ac6faba03525fb708cb5fd68fd40c5e

º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:º

As of feb 2021 you can do
bytes32 foo = "hello";
string memory bar = string(abi.encodePacked(foo));



-ºSTRING LIBRARIES:º
RºWARNº: String manipulation inside contracts is discouraged. It wastes lot of 
         gas and is error-prone. Use them as last-resort.

- @[https://github.com/Arachnid/solidity-stringutils]
   toSlice     (string self)                           internal returns (slice)
   copy        (slice self)                            internal returns (slice)
   toString    (slice self)                            internal returns (string)
   len         (slice self)                            internal returns (uint)
   empty       (slice self)                            internal returns (bool)
   compare     (slice self, slice other)               internal returns (int)
   equals      (slice self, slice other)               internal returns (bool)
   nextRune    (slice self, slice rune)                internal returns (slice)
   nextRune    (slice self)                            internal returns (slice ret)
   ord         (slice self)                            internal returns (uint ret)
   keccak      (slice self)                            internal returns (bytes32 ret)
   startsWith  (slice self, slice needle)              internal returns (bool)
   beyond      (slice self, slice needle)              internal returns (slice)
   endsWith    (slice self, slice needle)              internal returns (bool)
   until       (slice self, slice needle)              internal returns (slice)
   find        (slice self, slice needle)              internal returns (slice)
   rfind       (slice self, slice needle)              internal returns (slice)
   split       (slice self, slice needle, slice token) internal returns (slice)
   split       (slice self, slice needle)              internal returns (slice token)
   rsplit      (slice self, slice needle, slice token) internal returns (slice)
   rsplit      (slice self, slice needle)              internal returns (slice token)
   count       (slice self, slice needle)              internal returns (uint count)
   contains    (slice self, slice needle)              internal returns (bool)
   concat      (slice self, slice other)               internal returns (string)
   join        (slice self, slice[] parts)             internal returns (string)

- @[https://github.com/blockapps/blockapps-sol/blob/master/util/contracts/Util.sol]
  stringToBytes32(string memory input) pure returns (bytes32)
  bytes32ToString(bytes32       input) pure returns (string )
  b32            (string memory input) pure returns (bytes32)
  i2b32          (uint          input) pure returns (bytes32)
  a2b32          (uint[]        input) pure returns (bytes32[])
  uintToString   (uint          input) pure returns (string str)
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
Bº######################º
Bº# Function modifiers #º
Bº######################º
• Syntax sugar for function precondition checks:
@[https://en.wikipedia.org/wiki/Precondition]
• Commonly used to check basic "value security rules" 
  (correct ownership, enough funds, ...)
• Not recomended, but still in wide use.
  Syntax:
 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
                   VISIBILITY MODIFIERS (v0.5+)
                   ====================
     º[internal]º← only this contract and child ones
     º[private]º ← only this contract
     º[external]º← will only ever be called externally            [evm.gas]
                   external is more efficient than public
                   since it also avoid copying parameters twice
                   (very important with big arrays!!!)
    Bº[public]º  ← will also be called internally.

                   MUTABILITY MODIFIERS
                   ====================
    Oº[payable]º ← allows fun. to receive ether when called as:
                    myContractInstance.myPayableFunction.call.
                      value("ETH_TO_BE_SENT")("ADDITIONAL_DATA")
                    Ej: function deposit() payable {
                          deposits[msg.sender] += msg.value;
                        };
    Oº[pure]º    ← does NOT modify the contract storage
                   and storage can NOT be accesed
                   (utility libraries, ...)
    Oº[view]º    ← does NOT modify the contract storage
                   but storage can be accesed  ("getters")
    Oº[constant]º  (alias for pure)
    [returns ('return types')]
    {
      // (function body)
      ...
    }

Note:
     confirmPurchase(...) # Internal call
this.confirmPurchase(...) # External call
ERROR CONTROL
@[https://solidity.readthedocs.io/en/v0.4.24/control-structures.html#error-handling-assert-require-revert-and-exceptions]

BºError Management:º
  - Solidity uses state-reverting ("rollback") exceptions to handle errors:
    Capturing ("try-catching") Exceptions IS NOT POSSIBLE:
      EVM rollbacks any stat change in current call and all its sub/super-calls
     ºincluding any events emitted up until the rollback.º
      (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, but
    the execution of the mined will not modify any state. TX will just consume
    gas and record information about the error.
    See Example failed TX mined:
  @[https://etherscan.io/tx/0x9f00a37416a64735b02ab76da4477ea297bfd4923b1564c1b3579d542b3f4071]


  └ºassert( "my code-logic assertion");º
    - Represent a condition that must never happen unless
      there has been a solidity programming error.
    - Check for conditions and throw an exception
      if the condition is not met
    - Should only be used to test for internal
      errors, and to check invariants
    - If used properly, analysis tools can
      evaluate your contract to identify
      the conditions and function calls which will
      reach a failing assert.
      Properly functioning code should never reach
      a failing assert statement
    - compiles to INVALID 0xfe instruction
    - TheºEVM automatically raise assert-like exceptionsºwhen
      - access array at index greater than array length (or negative)
      - access fixed-length bytes"N" at a too large or negative index
      - divide or modulo by zero (ex.: 5 / 0 , 23 % 0)
      - shift by a negative amount
      - convert a value too big|negative into an enum type
      - call to zero-initialized variable of internal function type
      - call assert with an argument that evaluates to false
      - call function not matching any func. in contract
    -RºConsume all gas available to the callº
    - Error "rethrow"/"bubble up" in sub-calls

  └ºrequire("required cond.", "error messsage");º
    - pre/post check in in/out-data to function
    - Check for conditions and throw an exception
      if the condition is not met
    - Should be used to ensure valid conditions,
      such as inputs, or contract state variables
      are met, or to validate return values from
      calls to external contracts
    - optionally a message-string can be provided
    - compiles to REVER 0xfd instruction
    - Error "rethrow"/"bubble up" in sub-calls
    -BºDo not consume gas(v.Metrópolis+)º (Re-check this claim)

    - TheºEVM automatically throw requike-like exceptionsºwhen
      call a function via a message call but it does not
      finish properly (i.e. it runs out of gas, has no
      matching function, or throws an exception itself),
      except when a low level operation call, send,
      delegatecall or callcode is used.

  └ if ("business condtion")ºrevert("error message");º
    - business logic exceptions, like invalid request
      for current state.
    - can be used to flag an error and revert the
      current call.
    - It is possible to provide a string message
      containing details about the error that will
      be passed back to the caller.
    - Error "rethrow"/"bubble up" in sub-calls
    -BºDo not consume gas(v.Metrópolis+)º (Re-check this claim)

RºWARNº: low level ops return false, no assert/require/revert exception is raised.
   Example of low levels conditions returning false:
   (or true when called account is non-existent,
    Existence must be checked prior to call)
   - create a contract using "new" but contract creation does not finish properly.
   - perform external function call targeting a contract that contains no code
   - contract receives Ether via public function without payable modifier
     (including constructor or fallback)
   - contract receives Ether via public getter function
   - .transfer() fails

☞ 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). Ex:
    revert("Not enough Ether provided.");
    └───────────────┬───────────────────┘
    The following string of hexadecimal digits data  (vs byte array) will be 
    set as error return data:
    (NOTE: no carry-return exists in real output. Fake layout just for clarity)

    0x08c379a0                                                       ← Function selector for Error(string)
    0000000000000000000000000000000000000000000000000000000000000020 ← String offset  ┐
    000000000000000000000000000000000000000000000000000000000000001a ← String length  │ String 
    4e6f7420656e6f7567682045746865722070726f76696465642e............ ┐                ├─ABI encoding
    ................................................................ ├ String payload │
    ................................................................ ┘ (utf8 hex enc) ┘

Bºrevert reasonº
  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]);
      ...
    }
    ...
  }

  Related. Extracted from:
  @[https://besu.hyperledger.org/en/stable/HowTo/Send-Transactions/Revert-Reason/]

  besu requires the flag '--revert-reason-enabled' to include the revert reason in
  the TX receipt
  Rº: It may use a significant amount of memory when connected to public  netsº

  - When revert reason is enabled, the revert reason is included as an
   ABI-encoded string in the transaction receipt returned by eth_getTransactionReceipt.

  RºImportantº:
    revert reason is not included in the transactions receipts root hash.
    This means that the revert reason is only available to nodes that execute the
    transaction when importing the block.  That is, the revert reason is
  RºNOT available if using fast syncº

  Example TX Receipt:
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
       "from": "0x6273...57",
       "blockHash": "0xe72...0a",
       ...
     Oº"revertReason"º:"0x08c379a.....000"
     }                     ^
   }                       │
  ┌────────────────────────┘
  └─ Format: (Official  Solidity documentation),
     - ABI-encoded string consisting of:
       0x08c379a0                                                         // Error-Func.Sel.(string)
       0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset
       0x000000000000000000000000000000000000000000000000000000000000001a // String length
       0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data
         ^ Decodes to: "Not enough Ether provided"

     - Ex code extracting revert reason in Web3j:
       ...
       import org.web3j.protocol.core.methods.response.TransactionReceipt;
       import org.web3j.protocol.exceptions.TransactionException;
       import java.util.concurrent.CompletableFuture;

          try {
            // ... some code waiting for TX mining results
            CompletableFuture futureResult = new CompletableFuture();
                             myContractProxy.doSendLog2BlockchainAsync(some_input_data, futureResult);
          } catch(Throwable e /* capture "everything */) {
            if (e instanceof TransactionException) {
              TransactionException te = (TransactionException) e;
              Optional tr = te.getTransactionReceipt();
              if (tr.isPresent()) {
                // https://dhondt.tech/blog/2019/1/Web3j-retrieve-revert-reason.html
                System.err.println"revert reason:"+tr.get().getRevertReason());
              } else {
                System.err.println("txReceipt not present");
              }


Bº#############################º
Bº# try/catch (Solidity 0.8+) #º
Bº#############################º
  - Ex extracted from @[https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol

    try IERC1155Receiver(to).onERC1155Received(... )
        returns (bytes4 response) {
      if (response != IERC1155Receiver.onERC1155Received.selector) {
          revert("ERC1155: ERC1155Receiver rejected tokens");
      }
    } catch Error(string memory reason) {
        revert(reason);
    } catch {
        revert("ERC1155: transfer to non ERC1155Receiver implementer");
    }
Solidity Best Patterns:
● Coding Convention List
  This section covers a series of recomendations in order to develop 
  Solidity smart-contracts in order to improve the quality of code 
  decreasing or eliminating common bugs as well as making code easier 
  to read among developers.
   By following next coding convention among developers, we try to 
  make code easier to read and understand. They are non normative and 
  developers can use them as a reference.

 • Use some sort of convention agreement to prefix/suffix array types
    (e.g. suffix `_list`) and some prefix/suffix for map (key/value)
    structures (e.g, suffix `_map`). Note that in Solidity arrays and list
    are considered "similar" structures (vs arrays and list in Java, where
    ussually the later has better and more suitable properties than the
    former), since arrays are used scarcely, increasing slowly with incomming
    transactions and read by index most of the time.
  
 • Use `/* ... */` comments to make the map structure even more easy to
   understand.  Remember: Smart Contracts are LEGAL contracts reflecting 
   rights and obligations. In next mapping it is not possible to understand 
   what address and uint refer to. The variable 'balances' is a map, 
   and array, something else (when using it later on in code)? What 'keys'
   refer to?
   
      mapping ( address , =˃ uint ) balances;
      address[] keys; 

   We can write it like: 

      mapping (
        address /* effective identity address */
        =˃ uint /* balances in tokens type 1  */ ) addressToBalance_map;
       
      address[] address_key_list /* keys used in addressToBalance_map */;

 • Variable types can easely become difficult to understand if 
   not documented properly.  Use prefixes to be even more explicit about
   their types. Example:
    uint256 timeout ;    // ← Problem . Secs or milisecs or number of blocks ?
    uint256 ms_timeout ; // OK 

 • In function declatarion use  multiple lines for visibility, 
   mutability and returns keywords. 

   Prefixing internal functions using C style underscore (`_`) can
   improve (somehow) readability in complex code.
   
    Alternative 1:                     Alternative 2 (PREFERRED)
    ==============                     =============
    function myFunction(            │  function _myFunction(
      uint256[] memory param1_list) │    uint256[] memory param1_lst)
      internal view returns         │  internal                     // visible inside S.C.   
      (uint256[] memory)            │  view                         // mutability: View Only
                                    │  returns (uint256[] memory)   // return value/s
                                       
 • Use human-readable names:
   Prefer `_gasReceipt` to `_g` or `signature_lst` over `s_lst`.

 • Avoid named return values (even if allowed by Solidity syntax).

 • Error Control:
   · Use "require" to check input condition.
   · Use "if (condition) revert(...)" to check business logic conditions.
   · Use "assert" to check programming errors (theorically "asserts" must never
     assert to true in deployed production contracts.
   · KEY POINT:  Make precoditions execute in sequence (vs inside 
                 concatenated 'if' statements). Never ever execute normal 
                 flow inside an 'if' precontions.

     (VERY) WRONG.                      │ WRIGHT
     =============                      │ ============
     function ... {                     │ function ... {
       if (precondition1 == true) {     │   require(precondition1 == true, "...");
         if (precondition2 == true) {   │   require(precondition2 == true, "...");
           if (precondition3 == true) { │   require(precondition3 == true, "...");
             ... business logic         │   ... business logic  ...
           }                            │
         }                              │
       }                                │
     }                                  │  }



 • USING STATE MACHINEs:
   Many smart contracts can be reduced "somehow" to a description of "who is
   allowed to do what under which circumstances". This is basically an state-machine.
   Incomming Transfers are just events indicating the "who" in the signature. 
   By clearly indicating the state machine the code will be much more readable,
   easier to mantain and less prone to errors.

 • FAIL-FAST: @[https://en.wikipedia.org/wiki/Fail-fast]
    As a rule of thumb, if a function doesn't know what to return it 
   must revert the transaction (Remember: we are managing money). Add 
   `OrThrow` prefix to make the intention clear to (third-parties) 
   client code. Example:

     1 function getDelegatedAddressOrThrow(address _input_address)
     2 public
     3 external
     4 returns (address)
     5 {
     6     require (_input_address != 0, "BILLION_DOLAR_MISTAKE");
     7     address delegatedAddress = delegationDDBB[_input_address];
     8     require (delegatedAddress != 0, "INPUT_NOT_FOUND");
     9 }
    10
    11 function hasDelegatedAddress(address _input_address)
    12 public
    13 external
    14 returns (address)
    15 {
    16     require (_input_address != 0, "BILLION_DOLAR_MISTAKE");
    17     returns delegationDDBB[_input_address] != 0;
    18 }
    19
    20 function getDelegatedAddressOrDefault(address _input_address, address _default)
    21 public
    22 external
    23 returns (address)
    24 {
    25     require (_input_address != 0, "BILLION_DOLAR_MISTAKE");
    26     address delegatedAddress = delegationDDBB[_input_address];
    27     if (delegatedAddress == 0) return _default;
    28     return delegatedAddress;
    29 }

    In the previous code `getDelegatedAddressOrThrow` has no way to know 
    if `_input_address` was correctly sent by the client (code outside 
    Solidity control), or the value has not yet been updated (race 
    condition, previous failure, ...). Code just "reverts and forgets". 

    Client apps that want to know the value for a potentially 
    unregistered / non-delegated address will check first calling to 
    hasDelegatedAddress ("a la Python"). 

     It could be the case that client code has information enought to use 
    a default value.  In that case we can add a `getDelegatedAddressOrDefault`
    to let client use a single query to the blockchain. This is faster, 
    but potentially more error-prone. 

      WARN: `error-free code` is better than `fast code`. 
     Notice also how we protect against the billion-dolar mistake: 
   @[https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions]
     from incoming client code data by always avoiding "ZERO" like values
     (that potentially means an unitialized/undefined/null variable in 
      client code calling the smart-contract logic).

  • Use dependency injection extensively in constructors, spliting contracts into
    smaller ones. In practice, component injection is done manually in the 
    deployment scripts.


● Solidity (EVM actually) Limitations:
  • Stack effective size and EVM design by extension is very limited.
    When it grows beyond 16 elements old elements are not accesible
    anymore (compilation fails).
    This is enough to move balances from account to account, lock 
    or do atomic swaps, ... but not much more.
  • Contract size is limited (in public/semi-public networks). 
    Compiler will acept long contracts, but then the deployment will fail.
  • String support is limited (this is something good!, don't use them)
Storage
storage patterns
@[https://ethereum.stackexchange.com/questions/13167/are-there-well-solved-and-simple-storage-patterns-for-solidity]
Context:
   Simple and appropriate data organization can challenge Solidity newcomers.
   It wants us to organize everything in ways many of us aren’t accustomed to.
Q: 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.
RºWARNº:
   Event logs omitted for brevity in example code.
 BºIn real code they MUST be emitted for any state change.º

  MAPPING WITH STRUCT            │SIMPLE LIST USING ARRAY      │STRUCT ARRAY WITH UNIQUE IDS   │ ºMAPPED STRUCTS WITH INDEXº    │ºMAPPED STRUCTS WITH DELETE-ENABLED INDEXº º*1º
  ====================           │=======================      │============================== │ ===========================    │ ==========================================
ºSTRENGTHS                       │STRENGTHS                    │STRENGTHS                      │ STRENGTHS                      │STRENGTHS º
  Random access by unique Id     │· Reliably chronological     │· Random access by Row number  │ · Random access by Unique Id   │· Random access by Uniq.Id
  Assurance of Id Uniqueness     │  order of insertion         │· Assurance of Id uniqueness   │   or row number                │  or row number
  Enclose arrays, mappings,      │· Provides a count           │· Enclose arrays, mappings     │ · Assurance of Id uniqueness   │· Assurance of Id uniqueness
  structs within each "record"   │· Random access by Row       │  and structs with each        │ · Enclose arrays, mappings and │· Enclose arrays, mapping and
                                 │  Number (not Id)            │  "record"                     │   structs within each "record" │  structs within each "record"
                                 │                             │                               │ · List maintains declaration   │· Count the records
                                                                                               │   order                        │· Enumerate the ids
                                                                                               │ · Count the records            │· Logically control the size of
                                                                                               │ · Enumerate the Ids            │  the active list with delete function
                                                                                               │ · "Soft" delete                │
                                                                                               │   (by setting boolean value)   │


ºWEAKNESSES                      │WEAKNESSES                   │WEAKNESSES                     │WEAKNESSES                      │WEAKNESSES º
 · Unable to enumerate keys      │· No random access by Id     │- No random access by Id       │ · Uncontrolled growth of       │· Marginally increased code complexity
 · Unable to count the keys      │· No assurance of uniqueness.│- Uncontrolled growth of       │   the list                     │- Marginally higher storage costs
 · Needs a manual check to       │· No check for duplicates    │  the list                     │                                │- Key list inherently unordered
   distinguish default from      │· Uncontrolled growth of list│                               │                                │
   an explicitly "all 0" record  │                             │                               │                                │


  EXAMPLE Solidty version:  0.4.6
º EXAMPLE:                       │EXAMPLE:                     │EXAMPLE:                       │EXAMPLE:                        │EXAMPLE:º
 contract EntityDDBB {           │contract EntityDDBB {        │contract EntityDDBB {          │contract EntityDDBB {           │contract EntityDDBB {
   struct EntityStruct {         │  struct EntityStruct {      │ struct EntityStruct {         │  struct EntityStruct {         │  struct EntityStruct {
     uint data;                  │    address addr;            │   address addr;               │    uint data;                  │    uint data;
     bool isEntity;              │    uint    data;            │   uint    data;               │    bool exists;                │    uint lstPtr; /*list Pointer*/
   }                             │  }                          │ }                             │  }                             │  }
   mapping                       │ ºEntityStruct[]º public     │ EntityStruct[] public ddbb;   │  mapping                       │  mapping(address =˃ EntityStruct)
    (address =˃ EntityStruct)    │    ddbb;                    │ mapping(address =˃ bool)      │    (address =˃ EntityStruct)   │    public ddbb;
       public ddbb;              │                             │   knownEntity;                │      public ddbb;              │  address[] public list;
                                                                                               │  address[] public entityList;  │


   function exists(address addr) │                             │ function exists(address addr) │  function exists(address addr )│ function exists(address addr )
     public constant             │                             │     public constant           │      public constant           │      public constant
     returns(bool isIndeed) {    │                             │     returns(bool) {           │      returns(bool)          {  │      returns(bool) {
     return  ddbb[addr].isEntity;│                             │   return knownEntity[addr];   │    return ddbb[addr].exists;   │    if(list.length == 0) return false;
   }                             │                             │ }                             │  }                             │    return  ddbb[addr].lstPtr] == addr;
                                                                                                                                │ }
                                                                                                
                                 │  function getEntityCount()  │ function getEntityCount()     │  function getEntityCount()     │ function getEntityCount()
                                 │     public constant         │      public constant          │      public constant           │     public constant
                                 │     returns (uint) {        │      returns(uint) {          │      returns(uint) {           │     returns(uint entityCount) {
                                 │    return ddbb.length;      │   return ddbb.length;         │    return entityList.length;   │   return list.length;
                                 │  }                          │ }                             │  }                             │ }
                                                                                                
   function newEntity            │  function newEntity         │ function newEntity(           │  function newEntity(           │ function newEntity(
       (address addr, uint data) │     (address addr,          │     address addr, uint data)  │     address addr, uint data)   │     address addr, uint data)
       public returns(bool) {    │      uint data )            │     public                    │     public                     │     public returns(bool success) {
     if(isEntity(addr)) throw;   │     public                  │     returns(uint rowNum) {    │     returns(uint rowNumber) {  │   if(isEntity(addr)) throw;
     ddbb[addr].data  = data;    │    returns(uint rowNumber) {│   if(isEntity(addr)) throw;   │    if(isEntity(addr)) throw;   │   ddbb[addr].data = data;
     ddbb[addr].isEntity = true; │    EntityStruct memory aux; │   EntityStruct memory aux;    │    ddbb[addr].data = data;     │   ddbb[addr].lstPtr =
   }                             │    aux.addr = addr;         │   aux.addr = addr;            │    ddbb[addr].exists           │     list.push(addr) - 1;
                                 │    aux.data    = data;      │   aux.data = data;            │       = true;                  │   return true;
                                 │    return ddbb.push(aux)-1; │   knownEntity[addr] = true;   │    return                      │ }
                                 │  }                          │   return ddbb.push(aux) - 1;  │    entityList.push(addr) - 1;  │
                                 │                             │ }                             │  }                             │
                                                                                                
   function updateEntity         │                             │ function updateEntity         │  function updateEntity         │ function updateEntity(
      (address addr, uint data)  │                             │    uint rowNum, address addr, │      (address addr, uint data) │     address addr,
      public {                   │                             │    uint data                  │      public {                  │     uint data)
     if(!isEntity(addr)) throw   │                             │    public {                   │    if(!isEntity(addr)) throw;  │     public returns(bool success) {
     ddbb[addr].data = data      │                             │   if(!isEntity(addr)) throw;  │    ddbb[addr].data = data;     │   if(!isEntity(addr)) throw;
   }                             │                             │   if(ddbb[rowNum].addr!=addr) │  }                             │   ddbb[addr].data = data;
                                 │                             │      trhow;                   │                                │   return true;
                                 │                             │   ddbb[rowNumber].data = data;│                                │ }
                                 │                             │ }                             │                                │
                                                                                                
   function delete(address addr) │                             │                               │                                │ function delete      (address addr)
     public {                    │                             │                               │                                │     public returns(bool success) {
     if(!isEntity(addr)) throw   │                             │                               │                                │   if(!isEntity(addr)) throw;
     delete ddbb[addr];          │                             │                               │                                │   uint rowToDelete = ddbb[addr].lstPtr;
   }                             │                             │                               │                                │   address keyToMove = list[list.length-1];
                                 │                             │                               │                                │   list[rowToDelete] = keyToMove;
                                 │                             │                               │                                │   ddbb[keyToMove].lstPtr
                                 │                             │                               │                                │     = rowToDelete;
                                 │                             │                               │                                │   list.length--;
                                 │                             │                               │                                │   return true;
                                 │                             │                               │                                │ }
                                 │                             │                               │                                │
 }                               │}                            │}                              │}                               │}

  º*1º REF:
   Rob Hitchens@Medium  @[https://medium.com/@robhitchens/solidity-crud-part-2-ed8d8b4f74ec#.ekc22r5lf]
   Source Code          @[https://bitbucket.org/rhitchens2/soliditycrud/src/83703dcaf4d0c4b0d6adc0377455c4f257aa29a7/contracts/?at=master]
Composed-keys in maps:
@[https://ethereum.stackexchange.com/questions/69727/map-multikey-how-to]

•ºAlt1: create key like hash of N input composing keys
  Use events to trace input requests. e.j:
  bytes32 hashOfMultiKey = keccak256(abi.encodePacked(key1,key2)); 
  emit SomeEvent(key1, key2, bytes32 hashOfMultiKey, ...); ← event let observers track keys

  RºWARNº: original keys are lost in contract state.

•ºAlt2: Map of Mapº:
  mapping(                         ← allow to search by key1 or (key1,key2)
    bytes32            /*key1*/ =    More costly but keeps info. 
      mapping( bytes32 /*key2*/      
        =˃ bytes32)
  );

  mapping(                         ← allow searchs by key2 or (key2,key1)
    bytes32            /*key2*/ =    (if key2 is not a subkey of A)
      mapping( bytes32 /*key1*/      
        =˃ bytes32)
  );
Sorted Linked List
@[https://github.com/vittominacori/solidity-linked-list]
• utility library for using sorted linked list data structures.
• Well maintained as of 2022-01
• Public methods:
  listExists | nodeExists | sizeOf
  get(Node|Adjacent|NextNode|PreviousNode|SortedSpot)
  insertAfter | insertBefore | remove
  pushFront | pushBack
  popFront  | popBack
  

• EnumerableSet:
@[https://docs.openzeppelin.com/contracts/2.x/api/utils#EnumerableSet]

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/Dyn. 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
FORMAL PROOFs
• External Links
  • @[https://github.com/pirapira/eth-isabelle]
  • @[https://github.com/pirapira/ethereum-formal-verification-overview]
  • @[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)

SMTChecker • SMTChecker formal verification activated by default in Solidity compiler 0.8.4+ ('pragma experimental SMTChecker;') in previous versions. @[https://github.com/ethereum/solidity/blob/develop/docs/smtchecker.rst] • Perform automated mathematical-proof that source code fulfills a certain formal specification. The specification is still formal (just as the source code), but usually much simpler. • other verification targets that SMTChecker checks at compile-time are: - Arithmetic underflow and overflow. - Division by zero. - Trivial conditions and unreachable code. - Popping an empty array. - Out of bounds index access. - Insufficient funds for a transfer. • // SPDX-License-Identifier: GPL-3.0 pragma solidity ˃=0.8.0; contract Overflow { uint immutable x; uint immutable y; function add(uint _x, uint _y) ºinternalºpure returns (uint) { return _x + _y; ←┐•Commenting 'require(...)' will warn: } │ ...Overflow, val. larger than 2**256 - 1 } │ happens here. Counterexample: constructor │ x = 1, y = 11579208923731619...639935 (uint _x, uint _y) { │ x + y returns 0 (x, y) = (_x, _y); │ } │ ┌ Overflow TX trace ──┐ │ │ ... │ function stateAdd() │ │ Overflow.stateAdd() │ ºpublicº view returns (uint) { ←┤ │ │ require( ←┘ │ return _x + _y; │ x ˂ type(uint128).max); │ ^^^^^^^ │ require( └─────────────────────┘ y ˂ type(uint128).max); return add(x, y); } } Why3 Solidity • Why3: platform for deductive program verification with rich language for specification and programming, called WhyML, relying 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. """ • toolkit GUI: • why3 itself is only a frontend to the real workhorses: the provers. STEP 1). Install prover """... I tried ""alt-ergo"" (part of Ubuntu distribution) and Z3 (binaries for most platforms)..." STEP 2). $º$ why3 config --detect º← """ it should detect your prover.""" Video Tutorial: https://www.youtube.com/watch?v=Mzh4fyoaBJ0⅋feature=youtu.be⅋list=PL9oaY6Y4QxRZybj86eGItGVApxLXVIXHz See also: Virt.Machine for interactive Theorem Provers @[https://chriseth.github.io/notes/talks/formal_devcon2/#/] @[http://www.cs.umd.edu/~aseem/solidetherplas.pdf]
(Py)Slither
@[https://github.com/crytic/slither]
- Solidity source analyzer
- Detects vulnerable Solidity code with low false positives
- Identifies where the error condition occurs in the source code
- Easily integrates into continuous integration and Truffle builds
- Built-in 'printers' quickly report crucial contract information
- Detector API to write custom analyses in Python
- Ability to analyze contracts written with Solidity ˃= 0.4
- Intermediate representation (SlithIR) enables simple, high-precision analyses
- Correctly parses 99.9% of all public Solidity code
- Average execution time of less than 1 second per contract


Tools:
-Gºslither-check-upgradeabilityº: Review delegatecall-based upgradeability
-  slither-flat: Flatten a codebase
-  slither-erc: Check the ERC's conformance
-  slither-format: Automatic patches generation


ºUssage:º
$ slither .  # ← Truffle/Embark/Dapp/Etherlime application

$ slither .../Contract01.sol # Single solidity file:

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]
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 Bºvisualizes function control flow of a Solidity contract and highlights potentialº
 Bº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
• Problem Context: Compiler tries to access a variable var1 that is beyond 
  "16 depth in stack".  Compilation fails with error "stack too deep".
  EVM stack can be bigger than 16 elements, but OPCODES just can work with the closer 16 
  due to opcode limitations (DUP1, DUP2, ... DUP16).

• Solution 1: 
  Starting with Solidity 0.8+ ABIv2 is considered establed and we can use it to invoque 
  functions using structs that groups a bunch of imput parameters saving stack space.

  ABIv1                        ABIv2
  ======                       =====
  function XXX(                struct InputParams(
       param1_in_stack,             param1, 
       param2_in_stack,             param2,
       param3_in_stack,             param3,
       ... ) {                      ... 
  }                            }
                                
                               function XXX (InputParams param1_in_stack )


• Solution 2: ("Patchy" but it works when nothing else does).
  When var1 is still accesible, copy it again to var1_clone like
  function XXXX(uint param1_in_stack, ..., ... ,....)  {
     ...
     uint var1_clone = param1_in_stack;
     ...
     someMap[var1_clone] = ...; // ← At this point var1_clone is still on the stack
                                     but param1_in_stack is "too far away"
  }

     FUNCTION
     STACK FRAME
     -----------
   0 local var3  ←  Copy, for. ex, input arg1 here to have access once stacks grows "too much"
   1 local var2
   2 local var1
   ...
  15 input  arg3 ┐  Created at function call. Since those are the deepest in
  16 input  arg2 ├─ the stack, they are the first to cause "stack too deep" problems
  17 input  arg1 ┘
  17 'return value' ← return statement cleans the stack and places result values here

  -º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.                                                         º

RºWARN:º (@[https://blog.aventus.io/stack-too-deep-error-in-solidity-5b8861891bae])
Rº"...more difficult cases arise when calling functions in otherº
Rº 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..."
Full Examples:
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,Tokens,...
Asset Tokens
Universal Token
@[https://github.com/ConsenSys/UniversalToken]
- "A Unique Standard for Centralized and Decentralized Finance Use Cases"
- Actively maintained as 2021-10
- Inspired by ERC-2020 and Hash Time Locked Contract and (HTLC) implementations.

- Certificate-based token transfers:
@[https://github.com/ConsenSys/UniversalToken/blob/master/contracts/certificate/README.md]
  - ERC-1400 extends ERC-20 by allowing an extra "data" payload.
  - Codefi Assets uses the data to send a certificate generated off-chain by the issuer.
    At (Solidity) TX execution, 'ec-recover' is used to recover the
    signature of the certificate signer and then compared to the list
    of signatures authorized by the contract.
  -BºSort of multi-signature within 1 transaction. ← !!!º
      signature of the investor (ethereum transaction signature)
    + signature of the issuer   (embedded certificate signature)

  - Designed to enable issuance ofBºANY type of asset or financial instrumentº: 
      - DeFi derivative.
      - loan
      - mortgage
      - retail
      - wholesale CBDC,
      - ...
      - invoice
      - contract
      - gaming asset.

  - compatible with ERC20 and ERC1400.

- Delivery-vs-payment:
@[https://github.com/ConsenSys/UniversalToken/blob/master/contracts/tools/DVP.md]
  Use-case: allow secure token transfers/exchanges between 2 stakeholders 
  ("holder1" and "holder2" in secondary market assets transfers.

- Fund issuance:

Bº####################º
Bº# FUNGIBLE TOKENS: #º
Bº####################º
  └ºERC-20 Fungible Tokenº:
    - REF:
      -@[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md]
      -@[https://theethereum.wiki/w/index.php/ERC20_Token_Standard]
      - Problems with the Standard:
      @[https://edcon.io/ppt/two/Dmitry%20Khovratovich_Secure%20Token%20Development%20and%20Deployment_EDCON.pdf]
    - Standard interface to Fungible Assets Contracts that
     ºdifferent walletsº will understand out-of-the-box. A list of
      ERC20 compliant wallets can be found at:
    @[https://tokenmarket.net/what-is/ethereum-token-wallets/]

    └ºERC-777 Fungible Token (ERC-20 Extension)º:
      - extension backward compatible with ERC-20 including:
        - operators to send tokens on behalf of another contract|external acct.
        - send/receive hooks to offer token holders extended control.
      - It takes advantage of ERC-820 to find out whether and where to
        notify contracts|external-acct when they receive tokens as
        well as to allow compatibility with already-deployed contracts.
      - Master Tessis @[https://github.com/0xjac/master-thesis]

    └ºERC-223 (ERC-20 Extension)º:
      - REF: @[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..."
      
         "A" SENDING     CONTRACT send  1 Ether      , 1   Token       to "B"
         "B" DESTINATION CONTRACT is  NON-Ether aware, NON-Token aware.
         Result:
         A  →  B: 1ETH   ← GºOKº, rejected
         A  →  B: 1TOKEN ← RºKOº, possibly accepted since "B" can NOT recognize
                                  incoming TX.
                                Rºtokens stuck at the "B" balanceº
    └ºERC-1400 (ERC-20 Extension)º:
      - Allows to send arbitrary extra data. This data is used for example by
        Consensys "Universal Token" to attach an X.509 certificate as explained in
        @[#universal_token_summary]

    └ºERC-621 (ERC-20 Extension)º:
      - REF @[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-621.md]
      - ERC-20 extension.
      - Two additional functions added to increase/decrease liquidity:
        -ºincreaseSupplyº
        -ºdecreaseSupplyº
        ( ERC-20 allows a single token issuance event)

    └ºERC-827 (ERC-20 Extension)º:
    @[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-827.md]
      - ERC-20 extension for tokens with methods that allows the
        execution of calls inside transfer and approvals.

Bº########################º
Bº# NON-FUNGIBLE TOKENS: #º
Bº########################º
  └ºERC-721º:
  @[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md]
    - Standard interface for non-fungible ("deed") tokens,
      represent the ownership right/obligation over digital or
      physical assets. Ex:
      - house ownership rights.
      - loans obligations.
    
    - ERC-721 rights/obligations can be consigned to third party
      brokers/wallets/auctioneers ("operators").
    
    - Genobank.io Example:
      """ 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
      """

Bº#################º
Bº# MULTI-TOKENS: #º
Bº#################º
  └ºERC-1155º:
  Standard interface for contracts managing multiple token types.
  See @[#ERC_1155_summary]

Bº#############################º
Bº# SECURITY TOKENS: ERC-1400 #º
Bº#############################º
  - library of standards for security tokens on Ethereum.
  
    In aggregate provides a suite of standard interfaces for issuing /
    redeeming security tokens, managing their ownership and transfer
    restrictions and providing transparency to token holders on how
    different subsets of their token balance behave with Bºrespect to º
  Bºtransfer restrictions, rights and obligations.º
  
    - Standards should be backwards compatible with ERC-20 (#20) and
      easily extended to be compatible with ERC-777 (#777).
  
    - Depends on:
      - ERC-1410: differentiated ownership / transparent restrictions
      - ERC-1594: on-chain restriction checking with error
                  signalling, off-chain data injection for transfer restrictions and
                  issuance / redemption semantics
      - ERC-1643: document / legend management
      - ERC-1644: controller operations (force transfer)
Checking Signatures On-Chain
- ECDSA provides functions for recovering and managing Ethereum account
  ECDSA signatures. These are often generated via web3.eth.sign, and
  are a 65 byte array (of type bytes in Solidity) arranged the following
  way: [[v (1)], [r (32)], [s (32)]].

- The data signer can be recovered with ECDSA.recover, and its address
  compared to verify the signature. Most wallets will hash the data to
  sign and add the prefix '\x19Ethereum Signed Message:\n', so when
  attempting to recover the signer of an Ethereum signed message hash,
  you’ll want to use toEthSignedMessageHash.

RºWARNº:
- Getting signature verification right is not trivial: make sure you
  fully read and understand ECDSA's documentation.
@[https://docs.openzeppelin.com/contracts/2.x/api/cryptography#ECDSA]
EIP-1271
@[https://github.com/ethereum/EIPs/issues/1271]
- External "Dapps" can allow users to sign off-chain messages
  vs  directly requesting users to do an on-chain transaction.
  - Examples include decentralized exchanges with off-chain orderbooks
    like "0x" and "etherdelta".
- These Dapps usually assume that the message will be signed by
  the same address that owns the assets. However, one can hold assets
  directly in their regular account (controlled by a private key) or
  in a smart contract that acts as a wallet (e.g. a multisig contract).

- Current design of (many) smart contracts prevent contract based accounts
  from interacting with them, since contracts do not possess private keys
  and therefore can not directly sign messages.

- The proposal here outlines a standard way for contracts to verify if a
   provided signature is valid when the account is a contract.

- Realizing that this is more than just validating signatures; we're actually
  asking the question "given this action, does the caller have the ability
  to it, given this proof"?

- The standard defines an interface 'isValidSignature'. Implementations
  can call arbitrary methods to validate a given signature, which 
 ºcould be context dependent (e.g. time based, state based), EOA dependentº
 º(e.g. signers authorization level within smart wallet), signature schemeº 
  Dependent (e.g. ECDSA, multisig, BLS), etc.
   It should be implemented by contracts which desire to sign messages
  ("wallets", DAOs, multisignature wallets, etc.).
  Applications will can this method if signer is a contract (vs EOA).
ERC-1155
@[https://blog.enjincoin.io/erc-1155-the-crypto-item-standard-ac9cf1c5a226]
  - Standard interface for contracts managing multiple token types.

                 ┌─ N → fungible-token: 
                 │      in economic fungibility is the property
                 │      of a good or a commodity whose individual 
                 │      units are essentially interchangeable.
                 │      e.g: ERC-20, ERC-621, ERC-827
                 │
    ERC-1155  1 ←┼─ M → non-fungible-token "NFT" type 1
                 │      e.g: ERC-721: "games" NFT with Serial Number 
                 │      ("CryptoKitties",...)
                 │
                 ├─ O → non-fungible-token "NFT"  type 2
                 │
                 ├─ K → XXX (e.g, semi-fungible tokens)

  - NOTE: Some Multiplayer Games Have LOTS of different Items/Tokens
          - Runescape: 35,000+
          - World of Warcraft: 100,000+ different items!
          - Overwatch, Team Fortress 2: 1000's of skins + items.
 
  - Without ERC-1155:
  Rºfor each token and item type we require deploying a separate contractº
    (74000+ deployed tokens since 2015).
    Fungible and non-fungible tokens are not very compatible with each other.

  - With    ERC-1155:
      - configuration data per Token ID.
      - Atomic Multi-Transfers / Swaps :
      -ºfunctions 'transfer','approve','melt','trade' take      º
       ºarrays as parameters allowing for 100 to 200 operations º
       ºin a single transaction.                                º

   - ERC-1155 compliant MUST implement ERC-165 "supports" Interface
     function and return "true" for 0xd9b67a26 interfaceID argument.

   @[https://eips.ethereum.org/EIPS/eip-1155]
     - NOTE 1: `_operator`: address of an account/contract approved to make the transfer (SHOULD be msg.sender)
     interface ERC1155 /* is ERC165 */ {
         event TransferSingle( address indexed _operator, address indexed _from, address indexed _to, uint256 _id   , uint256 _value );
         event TransferBatch ( address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values);
         event ApprovalForAll(
           address indexed _owner,
           address indexed _operator,
           bool _approved
         );
         event URI( string _value, uint256 indexed _id);

         function safeTransferFrom(
           address _from, address _to,
           uint256 _id, uint256 _value,
           bytes calldata _data
         ) external;

         function safeBatchTransferFrom(
           address _from, address _to,
           uint256[] calldata _ids, uint256[] calldata _values,
           bytes calldata _data
         ) external;

         function setApprovalForAll(
           address _operator, bool _approved
         ) external;

         // VIEW:
         
         function balanceOf( address _owner, uint256 _id )
         external view returns (uint256);

         function balanceOfBatch(
                  address[] calldata _owners, uint256[] calldata _ids )
         external view returns (uint256[] memory);

         function isApprovedForAll( address _owner, address _operator )
         external view returns (bool);
     }

     ERC-1155 Token Receiver : MUST be implemented by S.C. accepting transfers.
     // ERC-165 identifier: 0x4e2312e0.

     pragma solidity ^0.5.9;

     interface ERC1155TokenReceiver {  // Receiver "hook" 
       function onERC1155Received(
         address _operator,
         address _from, 
         uint256 _id, uint256 _value,
         bytes calldata _data)
       external returns(bytes4);

       function onERC1155BatchReceived(
         address _operator,
         address _from,
         uint256[] calldata _ids,
         uint256[] calldata _values,
         bytes calldata _data
       ) external returns(bytes4);       
     }


ERC-1155 how to - PRESETUP: Get test tokens: → https://faucet.rinkeby.io → click "Give me ethers" (Follow instruction in page) - STEP 1. Create standard metadata (needed by wallets, marketplaces, ...). ┌ https://"meta"/.../0000...(64 hex zero-left padded) ..0000000001.json ┐ │{ │ │ "name" : "MY_FUNGIBLE_OR_NFT_TOKEN_NAME_1" , │ │ "description" : "Lorem Ipsum ..." , │ │ "image" : "https://imageURL/MY_FUNGIBLE_OR_NFT_TOKEN_NAME_1.png" │ │} │ └───────────────────────────────────────────────────────────────────────┘ ┌ https://"meta"/.../0000...(64 hex zero-left padded) ..0000000002.json ┐ │{ │ │ "name" : "MY_FUNGIBLE_OR_NFT_TOKEN_NAME_1" , │ │ "description" : "Lorem Ipsum ..." , │ │ "image" : "https://imageURL/MY_FUNGIBLE_OR_NFT_TOKEN_NAME_2.png" │ │} │ └───────────────────────────────────────────────────────────────────────┘ - STEP 2. Create Solidity code: (Example implementation with OpenZepellin) ┌─ REF: https://www.youtube.com/watch?v=SXp0sWmtuPc ───────────────────┐ │ │ │ // SPDX-Licence-Identifier: MIT │ │ pragma solidity ˃=0.8 ˂0.9.0; │ │ │ │ import "@openzepellin/contracts/token/ERC1155/ERC1155.sol"; │ │ │ │ contract MyCollectibles is ERC1155 { │ │ constructor() ERC1155("https://.../{id}.json") { │ │ _mint( msg.sender, 1 /* Id NFT Type 1 */, 10 /* Cantidad */, "");│ │ _mint( msg.sender, 2 /* Id NFT Type 2 */, 20 /* Quantity */, "");│ │ │ │ } │ │ } │ └──────────────────────────────────────────────────────────────────────┘ - Step 3: Use remix+Metamask or truffle deployments or ... to deploy to Rinkeby | MainNet | Private Net | ... - Step 4: Use some existing or custom "marketplace" to see the tokens. e.g: - @[https://rinkeby.rarible.com] - @[https://testnets.opensea.io/] (Rinkeby)
EIP-2981 ("Royalty Payments")
• Current state (no-standard):
  Artist → MarketPlace: "Do you support royalty payments?"
  Artist ← MarketPlace: "Yes we do, but if your NFT is sold
                         on another marketplace then we cannot
                         enforce this payment."
  Artist → MarketPlace: "Don't you share royalty info with others?"
  Artist ← MarketPlace: "No, we DO NOT"

  """ It is believed that the NFT marketplace ecosystem will voluntarily
      implement this royalty payment standard since NFT buyers 
      will assess the royalty payment as a factor when making NFT 
      purchasing decisions. """

• Standard proposal designed to support ongoing funding of original 
  NFT-creator or rights-holder to receive some quantity in future 
  re-sales of its art-work.
  interface IERC2981 is IERC165 {
      function royaltyInfo( uint256 _tokenId, uint256 _salePrice)
      external view returns (
          address receiver,
          uint256 royaltyAmount
      );
  }
  NOTE: it's not restricted to any other standard appart of ERC-165.

• ROYALTY PAYMENT MUST BE VOLUNTARY (by Marketplace), vs triggered by 
  "transferFrom()" like mechanism, since such transfer can just mean 
  movement to a different wallet of the same owner (vs new sale or 
  change of ownership).

• Marketplaces → SC: royaltyInfo()?
• Marketplaces ← SC: royalty payment information 
                     ===========================
                     - royaltyAmount to pay for a given sale price.
                       as a (calculated)ºpercentageºof _salePrice.
                     - recipient address 

 - royaltyInfo is not aware of _salePrice monetary-unit.
 - marketplaces MUST calculate final royalty price in the same monetary-unit 
   used by the _salePrice. 
 - if the calculated royaltyAmount is zero, no further processing is expected.
 - calculus of percentage is left un-specified mut marketplaces SHOULD 
   implement it, with next restriction:
   - It must be based on predictable variables (vs using block.timestamp,
     block.number, ...) and must not make assumptions about the unit
     of exchange.
   - Examples:
   - It can be a fixed inmutable percentage.for any future sale.
   - Percentage drops linearly over time.
   - Based on min/max thresholds.
ERC 777: Advanced Token Standard
@[https://medium.com/coinmonks/erc-777-a-new-advanced-token-standard-c841788ab3cb]
- Deprecated? in favor of ERC-1155.
- ERC-20 extension:
- introduced to establish an evolved Token standard which learned 
  from misconceptions like approve() with a value and the 
  send-tokens-to-contract-issue.

- Makes use of new standard ERC-820:
  Pseudo-introspection using a registry contract which allows for
  registering meta-data for contracts to provide a simple type of
  introspection. This allows for backwards compatibility and other
  functionality extensions, depending on the ITokenRecipient returned
  by a EIP-820 lookup on the to address, and the functions implemented
  by the target contract.

- Adds lot of learnings from using ERC-20 Tokens, eg.
  white-listed operators, providing Ether-compliant interfaces with
  send(...), using the ERC-820 to override and adapt functionality.
Identity+Governance
EIP 1056: Lightweight Identity
WARN: Unstable, likely to change.
""" ...As we have been developing identity systems for the last couple of 
  years at uPort it has become apparent that the cost of identity 
  creation is a large issue. The previous Identity proposal ERC-725 
  faces this exact issue. Our requirements when creating this ERC is 
  that identity creation should be free, and should be possible to do 
  in an offline environment (e.g. refugee scenario). However it must 
  also be possible to rotate keys without changing the primary 
  identifier of the identity. The identity system should be fit to use 
  off-chain as well as on-chain..."""


ERC725 Identity Note: Current Identity Systems in Ethereum include (ref: https://w3c-ccg.github.io/did-method-registry/#the-registry) did:erc725: PROVISIONAL Ethereum Markus Sabadello, Fabian Vogelsteller, Peter Kolarov erc725 DID Method did:uport: DEPRECATED Ethereum uPort did:ethr: PROVISIONAL Ethereum uPort ETHR DID Method did:dom: PROVISIONAL Ethereum Dominode did:jolo: PROVISIONAL Ethereum Jolocom Jolocom DID Method did:selfkey: PROVISIONAL Ethereum SelfKey SelfKey DID Method did:pistis: PROVISIONAL Ethereum Andrea Taglia, Matteo Sinico Pistis DID Method did:vaultie: PROVISIONAL Ethereum Vaultie Inc. Vaultie DID Method did:gatc: PROVISIONAL Ethereum, Gataca Gataca DID Method Fabric, Alastria did:signor: PROVISIONAL Ethereum Hashgraph Cryptonics Signor DID Method @[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; } } } }
ERC 780: Ethereum Claims Registry 
- proposal to allows persons, smart contracts, and machines to issue 
  claims about each other, as well as self issued claims with the aim 
  of providing a central point of reference for on-chain claims on 
  Ethereum.
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
Modular-Network Libs
@[https://github.com/modular-network/ethereum-libraries]
- ArrayUtilsLib
- BasicMathLib
- CrowdsaleLib
- LinkedListLib
- StringUtilsLib
- TokenLib
- VestingLib
- WalletLib
Development Tools[See also!!!]
External Links
@[https://github.com/ConsenSys/ethereum-developer-tools-list/blob/master/README.md]
@[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]
- Features:
- integrated smart-contract debugger.
- Integration with Github gist. Ex:
  https://remix.ethereum.org/#version=soljson-v0.7.2+commit.51b20bc0.js&optimize=false&gist=65747824fd972fcde14bac5101489032&evmVersion=null
MetaMask Plugin

RºWARN,WARN,WARN:º (Update 2019-12) Metamask management problems:
   @[https://www.bitcoininsider.org/article/79962/updated-metamask-contributor-says-project-lacks-support-consensys]
   - A contributor of major Ethereum browser extension Metamask has
     reported that the MetaMask team is “totally overwhelmed” and not
     being prioritized by its parent company ConsenSys.

     The post, titled “Help MetaMask out of its Activity-Trap,” goes
     on to say that the MetaMask team has a number of unsolved issues and
     its inner workflow structure is neither transparent nor
     decentralized. The post reads:

     “One cannot follow development via the public issue-tracker,
      simply because the team uses an internal tracker and internal
      ‘meetings.’ This is not transparent. This is not decentralized.
      MetaMask is a critical value-moving piece of Ethereum. It is written
      in JavaScript, nearly completely untyped. The code is of low quality,
      full of technical debt (both, in terms of code and architecture).”


@[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/] ver 8 (major upgrade) @[https://medium.com/metamask/announcing-metamask-version-8-9126dc2df98] - Unparalleled Privacy Control select one or more accounts to associate with a website or Bºcreate a new account just for that siteº. - new connection indicator, - EIP-2255 (site) permissions system. - enhanced permissions will enable powerful features like decryption, access to wallet information (like your favorite tokens or contacts), and paves the way for MetaMask Snaps extensibility. - Slick, New UI - More Features For Developers: - Web3 Encryption: two new methods to allow websites to encrypt and decrypt messages intended for Web3 users. - For now, these decryption requests each require user confirmation, so it’s mostly ideal for decrypting infrequent, important messages, like emails. - New onboarding library enabling Dapps to implement their own connect button. (allow user to seamlessly land on your site, install MetaMask, and be automatically redirected back to your application) - ERC-1193 Provider API: for consistency across clients and applications. Instead of (old) ethereum.sendAsync(options, callback) pattern everywhere, you now get a nice and simple const result = await ethereum.request({ method, params }). If you’re a developer that relies on the window.web3 object injected by MetaMask, you’ll need to implement changes before we remove the injected web3 object or your site will break. If you’re a developer that only relies on your own version of ethers or web3, you won’t need to take any action — just keep it up to date. BºIf you are choosing a new convenience library, we º Bºrecommend ethers.º - Cutting Edge Security BºThe (new) LavaMoat tool helps raise the bar of security forº Bºnearly any JavaScript project.º LavaMoat uses Secure EcmaScript to confine every third-party dependency in a piece of JavaScript code at build time. We hope to eventually confine every dependency in our entire wallet, greatly protecting us and our users from the category of “supply chain attacks”.
Lattice1 Integration • Metamask announced support for Lattice 1 as of 2021-11 @[https://consensys.net/blog/news/metamask-x-lattice1-the-hardware-wallet-designed-for-ethereum-users-is-now-supported/] • Lattice1 (by GridPlus): hardware wallet for Ethereum users. • MetaMask / Lattice1 is done through Wi-FI (vs USB). • Lattice1 aims to solve 3 big crypto security problems: • Leaking private keys: SafeCards securely back up seeds onto PIN-protected cards. Every SafeCard is essentially a physical carrier of an HD wallet seed that looks like a traditional credit/debit card. • Signing messages unintentionally: - big touch screen interface and human-readable markup. - supports for NFTs. - "enhanced" smart contract interaction. • great user experience in integrating with MetaMask.
EIP-712 (Typed human-friendly signing)
- EIP-712: Ethereum typed structured data hashing and signing 
@[https://eips.ethereum.org/EIPS/eip-712]
- See also @[#eip-191] 
- Introduction by Koh Wei Jie:
@[https://medium.com/metamask/eip712-is-coming-what-to-expect-and-how-to-use-it-bb92fd1a7a26]
  Ethereum wallets like MetaMask will soon introduce the EIP712
  standard for typed message signing Bºallowing wallets to º
Bºdisplay data in signing prompts in a structured and readable format.º
BºEIP712 is a great step forward for security and usability because º  [qa][usability]
Bºusers will no longer need to sign off on inscrutable hexadecimal  º  [security]
Bºstrings, which is a practice that can be confusing and insecure.  º

- Related:
  - Lattice 1 GridPlus Hardware Wallet:
  @[https://blog.gridplus.io/latice1-firmware-v0-10-6-da18ec10f5b]

  - 1st with Native EIP-712 Support for Use with Uniswap V3, Polygon, and More!

 ... When Uniswap V3 launched, liquidity providers were unable to
  migrate their positions because Uniswap uses a new message type
  (EIP712) which is not yet supported on legacy hardware wallets using
  MetaMask and their assets were stuck. Not an issue for Lattice1
  owners... Competitors have publicly shared that even when they do
  support the feature, they will not be using their device's secure
  enclave and will instead create hashes in your computer's web
  browser. Never use your hardware wallet to blindly sign unknown
  hashes.
meta-transactions
@[https://defirate.com/meta-transactions/]
In essence, meta transactions allow users to interact with a public
blockchain without paying a transaction fee. This leads to a more
seamless UX as users no longer have to understand the inner workings
of public blockchains and market dynamics for transaction fees.

At its core, meta transactions are nearly identical to regular
network transactions but with the addition of a proxy contract, also
known as a relayer. With meta transactions, users still use their
signature to send and authenticate transactions. The difference is,
once this happens, the transaction is now managed by the relayer who
pays the gas and sends the transaction to the receiving address.

By leveraging meta transactions, developers can significantly
streamline the user experience for their applications. Ultimately,
this feature brings the ecosystem closer to a frictionless user
experience when accessing web 3.0 and DeFi.
LedgerHQ
@[https://github.com/LedgerHQ]
Ledger wallets, designed with the highest security standards
See also LedgerJS examples:
@[https://github.com/LedgerHQ/ledgerjs-examples]

High activity on Github, including:
(non-complete list)
- ledger-live-common : JS, Common ground for the Ledger Wallet apps
- lib-ledger-core    : C++,
- TRX Ledger : C, app-exchange
- SWAP application: C
- ledger-wallet-daemon: Scala, Scala web server that expose
                        Ledger Core library through a simple REST API
- ledger-live-mobile: react-native, bluetooth
- ledger-live-desktop: electron,
- wallet  : JS,
- Bºopenpgp-card-app: C, OpenPGP Card Applicationº
- app-terra: C, Nano S/Nano X
- app-ethereum: C, Wallet App for Ledger Blue and Nano S
- app-bitcoin: C, Bitcoin wallet app for Ledger Blue and Nano S
- ledger-updater: JS,  Standalone firmware update / app installation tool
- ledger-scala-template: Scala, template for scala project
- ledger-dev-doc: Python, Ledger developer documentation
- ledger-app-store-front: JavaScript
- ledger-manager-chrome: Scala, Ledger Manager Chrome application
- ledger-wallet-chrome: JS, Ledger Wallet Chrome application
- ledgerctl: Python, Library to control Ledger devices
Web3JS API
Example ussage (works on browser/browser js console,  web3.js v1+):

 const ctr = new web3.eth.Contract(abiDefinition, ctrAddress) // ← get contract instance
 const txId = await ctr.methods.playGame().\                  // ← send TX to SC. Funct. playGame
              send({from: sendingAccount, value: amountInWei })

@[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

Recipes

BºCalculate keccak256 (hash/sha3) of N input arguments matching hash in Solidityº
  // https://web3js.readthedocs.io/en/v1.2.0/web3-utils.html#soliditysha3

  keccak256(abi.encodePacked(string1, address1,...))   ← ºSolidityº Which version is the correct one?
  keccak256(string1, address1,...                  )   ← ºSolidityº

  web3.utils.soliditySha3(                             ← ºWeb3.js, Alt 1º: Easiest way
      { type: 'string',  value: myString01     },
      { type: 'bytes32', value: myBytes32value },
      ...
  )

  web3.sha3(                                           ← ºWeb3.js Alt 2º: Manual hard way
     web3.utils.toHex("test1")   + "0A...20 bytes.."   ← 1st arg: ensure input is equal to the tightly packed
     └───────┬───────────────┘     └───────┬───────┘              args in Solidity keccak256
    tightly pack string to Hex     Don't  pack address
                                   or hex strings (Remove 0x)
     ,
     {encoding:"hex"}                                  ← 2nd argument. Encode like hex input
  );

BºConvert input String  to ABI representationº
  web3.eth.abi.encodeParameter("bytes32",web3.utils.fromAscii(ºinputStringº))
web3.js vs eth.js
https://blog.infura.io/ethereum-javascript-libraries-web3-js-vs-ethers-js-part-i/?utm_medium=www.oficina24x7.com
Ethereum JavaScript Libraries: web3.js vs. ethers.js (Part I)
- Both libraries work!!

- Web3.js:
  - 2015
  - Ethereum Foundation Community.
  - It has a good API reference.
  - GLP v3
  - it includes functions to communicate with nodes
    via the JSON-RPC.
  - current (2020-06) version: 1.2.9
  - composed of 6 modules:
    -  web3: main class. "Core functionality"
    - web3-eth:
      - API to interact with smart contracts, externally-owned
        accounts, nodes, mined blocks, and TXs. Ex:
        - web3.eth.getBalance
        - web3.eth.signTransaction
        - web3.eth.sendSignedTransaction
        - ...
    - web3-shh:
      Whisper protocol to broadcast messages easily and for
      low-level asynchronous communication. Ex:
      - web3.shh.post      ← posts whisper msg to Net.
      - web3.shh.subscribe ← creates subscription
      - ...
    - web3-bzz
      Swarm decentralized storage API :
      (files, images, ...). Ex:
      - web3.bzz.upload   ←   Upload files|folders to Swarm
      - Web3.bzz.download ← Download files|folders from "
    - web3-net
      - Interact. API for Network properties of a node.
        - web3.???.net.getID        ← return network ID
        - web3.???.net.getPeerCount ← returns peer number
               ^^^
            protocol of interest: eth|shh|bzz
    - web3-utils. Ex:
      - web3.utils.toWei
      - web3.utils.hexToNumberString
      - web3.utils.isAddress  ← check if string is a valid address.

- Ethers.js:
  - 2018
  - JS + TypeScript
  - small, compact library.
  - "Simple" and "intuitive".
  - large number of test cases.
  - Good "Getting Started" documentation.



- current (2020-06) ver.:  5.0.3.
- MIT License.
- Modules:
  - Ethers.provider
    - abstract connection to node/network.
    - sending signed TXs ("writes") and read-queries.
      - ethers.providers.InfuraProvider:  Infura "client"
      - ethers.provider.getBalance
      - ethers.provider.resolve ← resolve ENS to address

  - Ethers.contract
    - deploy S.C.
    - listen for events emitted
    - call functions
    - get S.C. information
    - Ex:
      - ethers.ContractFactory.fromSolidity:
        Creates "factory" for deployment of S.C. using
        as input:
        - Solc output or
        - Truffle generated JSON file
      - ethers.Contract : ← interact with deployed S.C.
  - Ethers.utils
    - formatting data , process user inputs.
    - Ex:
      - ethers.utils.getContractAddress: Address from deployment TX
      - ethers.utils.computeAddress    : pub/priv: key to address
      - ethers.utils.formatEther       : Wei s to decimal string
  - Ethers.wallets
    - connect to existing wallet, create new one, sign TXs.
    - Ex:
      - ethers.wallet.createRandom
      - ethers.wallet.sign
      -  ethers.wallet.getBalance
    - Equivalent to web3.eth.accounts, but in web3js doc it
      warns: "This package has NOT been audited and might
      potentially be unsafe. Take precautions to clear memory
      properly, store the private keys safely, and test TX
      receiving/sending properly before using in production!"

Comparative:
            starts|Used by|Maintainers|Test   |Size |Unpacked
                  |(repos)|           |support|     |
-   Web3.js:~8,800|51.300 |3 of 12    |       |     |10.6MB
- ethers.js:~1,500|18.500 |1(Richard  |"WINS" |284kb| 3.5MB
                             Moore)
- ethers.js has surpassed web3.js in weekly downloads
  (even if its younger)
Documentation:
  Web3.js: extensive API ref, Short "Getting Started"
Ethers.js: extensive API ref, Good “Getting Started”  ← Winner
Truffle
Slack Channel: @[https://truffle-community.slack.com/join/shared_invite/zt-8wab0bnl-KcugRAqsY9yeNJYcnanfLA]
"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   │ REF:
    |     //   =˃ saved in storage (vs memory)        │ @[https://github.com/trufflesuite/truffle-deployer/blob/develop/index.js]
    |     //    =˃ triggers TX when modified          │ function Deployer(options) {
    |     uint[] fibseries;                           │   var self = this;
    |     // n = how many in the series to return     │   options = options || {};
    |     function generateFib(uint n) public {       │
    |         // set 1st and 2nd entries              │   expect.options(options, [
    |         fibseries.push(1);                      │     "provider",
    |         fibseries.push(1);                      │     "network",
    |                                                 │     "network_id"
    |         // generate subsequent entries          │   ]);
    |         for (uint i=2; i ˂ n ; i++) {           │
    |             fibseries.push(fibseries[i-1] +     │   this.chain = new DeferredChain();
    |                            fibseries[i-2]);     │   this.logger = options.logger || {log: function() {}};
    |         }                                       │   this.known_contracts = {};
    |     }                                           │   (options.contracts || []).forEach(function(contract) {
    | }                                               │     self.known_contracts[contract.contract_name] = contract;
$ vim migrations/2_deploy_contracts.js:               │   });
WARN: ¡¡¡do not touch 1_initial_migration.js!!!       │   this.network = options.network;
    | var Fibonacci = artifacts.require("Fibonacci"); │   this.network_id = options.network_id;
                                                      │   this.provider = options.provider;
    | module.exports = function(deployer) {           │   this.basePath = options.basePath || process.cwd();
    │                           └──┬───┘              │ };
    │                              └──────────────────┘
    |   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 NOTE: Trufle 5.1 introduces also debugging from JS tests: 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))º → ... NOTE: bytecode vs deployedBytecode solc generates two bytecode blobs per contract that truffle relies on: - bytecode includes the wrapper code necessary to init and deploy the contract - deployedBytecode just contains the core, deployed code.
Migrations Explained
- truffle migrations explained (Linking libraries, ...):



- Migration "==" Javascript file to deploy smart-contracts to the blockchain.
  A JS migration script will fetch as input the

  $ truffle create \              ─────────┐
    migration deploy_myContract            │
                                           v
  $ truffle \ →(generates)→ JSON →(used by)→ migrations/...deploy_myContract.js
    compile                 artifacts                   └┬┘      
                                                   migration (ordered) number.
                       succesful migrations are recorded to "migration" smart-contract
                       "truffle migrate" will start execution from the last+1 registered migration.

  Ex. migration:
  const A  = artifacts.require('PersistenceContract')  ← artifacts.require() is similar to node.js "require"
             └─────────────────┬────────────────────┘    but it returns a contract proxy.
             Load PersistenceContract.json, and completes
             it will extra. info (function selector 4byte codes,..)
             Used to generate JSON-RPC calls.

  const LibA = artifacts.require('LibA')
  const B    = artifacts.require('Logic_dependingOnA')

  module.exports = function(deployer, network, accounts) { ← 'deployer', network(string) name and account array
    if (network == "test") {                                 injected by truffle.
       deployer.deploy(LibA);     ← Deploy runs synchronously. Code waits until transaction has been mined
                                    in blockchain.
       deployer.link(library, A)  ← ☞ Link must be done before deployment
                                    (Ignored if contract doesn't rely on the library)
                                    @[https://github.com/trufflesuite/truffle/tree/master/packages/contract]
       deployer.deploy(A)         ← Set "A".address after correct deployment
       deployer.deploy(B,           overriding any previous one.
              A.address,          ← First constructor argument of B (A instance)
              { overwrite: true } ← Other options: gas, from
          );
       } );
    } else if (network == "test") {
       // Fetch A address from "somewhere"
       deployer.deploy(
           B, A.address,
            { overwrite: false } );
    }
  };


Migrations.sol explained @[https://medium.com/@blockchain101/demystifying-truffle-migrate-21afbcdf3264?utm_source=oficina24x7] by Bernard Peh - truffle migrate uses a Migrations.sol instance to "bookmark" last succesful migration. Migrations.sol summary: ... contract Migrations { uint public last_completed_migration; ← On truffle console value can be check like: ... $º˃ Migrations.deployed().then( º $º function(sc){ º $º sc.last_completed_migration.call().then( º $º function(v) { console.log(v)} ) º $º } º $º ) º Qºfunction setCompleted(uint completed)º ← Invoqued whenever a migration/*.js script public { is completed successfully. last_completed_migration = completed; } ... (upgrade ) ... } º1st Migration executionº º2nd UPGRADED Metacoin migrationº migration SETUP: migration SETUP: └./migrations/1_initial_migration.js └./migrations/1_initial_migration.js └./migrations/2_deploy_contracts.js └./migrations/2_deploy_contracts.js └───────┬────┘ └./migrations/3_deploy_upgraded_metacoin.js ┌───────┘ └───────────┬───────────────┘ │ ┌─────────────────────┘ ... ... deployer.deploy(ConvertLib); // deployer.deploy(ConvertLib); ← Commented (Save gas) deployer.link(ConvertLib, MetaCoin); deployer.link(ConvertLib, MetaCoin); deployer.deploy(MetaCoin); deployer.deploy(MetaCoin); (or --reset flag added) $º$ truffle migrateº $º$ truffle migrateº Compiling ... ... ... last_completed_migration == 2 → start at migrations/3_*.js Running migration:Qº1_initial_migration.jsº (☞Migration and ConvertLib skipped) Deploying Migrations... Running migration:Qº3_deploy_upgraded_metacoin.jsº ... 0x68fe0... (deploy TX hash ) Replacing MetaCoin... Migrations: 0x213.... (Contract address) ... 0xe9d0481... (deploy TX hash ) QºSaving successful migration to network...º MetaCoin: 0xf55... (Contract address) ... 0xe2807... (setCompleted() TX hash) QºSaving successful migration to network...º Saving artifacts... ... 0xcf8f9... (setCompleted TX hash) Running migration:Qº2_deploy_contracts.jsº Saving artifacts... Deploying ConvertLib... ... 0xce792... (deploy TX hash ) ConvertLib: 0x13e... (Contract address) Linking ConvertLib to MetaCoin Deploying MetaCoin... ... 0x2fcab... (deploy TX hash ) MetaCoin: 0x0d9... (Contract address) QºSaving successful migration to network...º ... 0xe2807... (setCompleted() TX hash) Saving artifacts...
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            
  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.
Truffle IPFS/Filecoin
@[https://www.trufflesuite.com/blog/announcing-collaboration-with-filecoin]
(migrating to) web3 v1.0
@[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 ... (TODO)


Web3J (event) 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] fetch 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)))); } See Also: SpringBoot ERC-20 RESTfull ex: @[https://github.com/blk-io/erc20-rest-service/blob/master/src/main/java/io/blk/erc20/Controller.java]
GO
Web3 GOLang
 º===================================================º
•ºethclient package. Connecting to node (ws/http/ipc)º
 º===================================================º
@[https://medium.com/coinmonks/web3-go-part-1-31c68c68e20e]

  cl, err := ethclient.Dial(“/tmp/geth.ipc”)          // Ex.1:  Use local node
                                                      // (or http://$IP:$PORT for remote node)
                                                      // cl wraps a raw rpc.Client 

  infura := “wss://goerli.infura.io/ws/v3/xxxxxx”     // Ex.2: Use infura
  cl, err := ethclient.Dial(infura)
  //    
  ctx := context.Background()               ← Retrieve a block by number
  block, err := cl.BlockByNumber(
                   ctx, big.NewInt(123))
  // 
  addr := common.HexToAddress("0xb02A2...") ← Get Balance of an account (nil means at newest block)
  balance, err := cl.BalanceAt(ctx, addr, nil)
  // 
  tx := new(types.Transaction)     
  err = cl.SendTransaction(ctx, tx)         ← Send transaction: It will fail. tx is unsigned⅋empty
  // 
  progress, err := cl.SyncProgress(ctx)     ← Get sync progress for node

• accounts package:  
  Ex. Create raw transaction.
  nonce, err := cl.NonceAt(ctx, addr, nil)   ← Retrieve the pending nonce for an account
  to  := common.HexToAddress("0xABCD")
  amount := big.NewInt(10 * params.GWei)
  gasLimit := uint64(21000)
  gasPrice := big.NewInt(10 * params.GWei)
  data := []byte{}
  tx := types.NewTransaction(nonce,          ← Create new raw unsigned transaction
     to, amount, gasLimit, gasPrice, data)

                                               Sign TX with in-memory priv.key
                                               ===============================
  PK := "0x..."                              ← (p)rivate (K)ey as hex.formated string
  pk := crypto.ToECDSAUnsafe(                ← convert hex.string to ECDSA private key
            common.FromHex(PK))
  signedTx, err := types.SignTx(tx,          ← Sign tx (Discourages, better use the
          types.NewEIP155Signer(nil), pk)     ºTransactOptsºobject).
  addr := crypto.PubkeyToAddress(            ← ex. Obtain public key from private key.
          pk.PublicKey)
  opts := bind.NewKeyedTransactor(pk)        ← ex. create TransactOpts object from 
                                               in-memory priv.key

                                               Sign TX with offchain wallet/keystore
                                               ===============================
  ks := keystore.NewKeyStore(".../keystore", ← Open Keystore
        keystore.StandardScryptN,
        keystore.StandardScryptP)
  acc, err := ks.NewAccount("password")      ← Create an account in key Store
  accs := ks.Accounts()                      ← List all accounts in Key Store
  ks.Unlock(accs[0], "password")             ← Unlock account[0]
  ksOpts, err := bind.NewKeyStoreTransactor  ← CreateºTransactOptsºobject. 
                 (ks, accs[0])                 
  sigTx, err := ksOpts.Signer(               ← Use it to sign TXs. 
    types.NewEIP155Signer(nil),                TransactOpts Also needed to interact
    senderAddr, tx)                             with S.C. using auto-generated bindings.


 º=======================================================º 
•ºbind/abigen packages. Interacting with Smart Contracts:º 
 º=======================================================º 
@[https://medium.com/coinmonks/web3-go-part-2-aebdcb8d926e]
  It avoid to interact manually with ABI.
  • abigen, (included in full installation of geth)
  $º$ abigen --pkg coolcontract \          º
  $º  --sol CoolContract.sol  \            º  ← Input solidity contract.
  $º --out ./coolcontract/CoolContract.go  º  ← autogenerates (lot of useful) methods to deploy
                                                and interact with the contract.

• For any interaction we need an Object implementing ˂˂ContractBackend˃˃.
   backend, err := ethclient.Dial("/tmp/geth.ipc") ← returns ethclient.Client implementing 
                                                     ˂˂ContractBackend˃˃
   addr := common.HexToAddress("0x0..")            ← deployed S.C. address as hex.string
   ctr, err := contract.NewContract(addr, backend) ← Bind to already deployed contract
                                                     (contract: generated by abigen)
                                                     To deploy new contract instead:
                                                     addr, tx, ctr, err := 
                                                         coolcontract.DeployCoolContract(
                                                             transactOpts, backend)
                                                     _, err = bind.WaitDeployed(ctx, backend, tx)

   callOpts := ⅋bind.CallOpts{
                  Context: ctx, Pending: false
               }
   bal, err := ctr.SeeBalance(callOpts)           ← Call pure/view (read-only) function. 
                                                    no mining needed.
   tx, err := ctr.Deposit(transactOpts)           ← Execute transaction (mining needed)
   receipt, err := bind.WaitMined(ctx, backend, tx) 
   if receipt.Status != types.ReceiptStatusSuccessful {
     panic("Call failed")
   }

 º================º
•ºEvent listening:º
 º================º
@[https://medium.com/coinmonks/intro-to-web3-go-part-3-d4f08a32c0ae]
  └ filtering for (OLD!!!) events: (abigen autogenerated Filter˂EventName˃ )
      create bind.FilterOpts with start/end block arguments.
      WARN: only works on full (archive) nodes.
      WARN: It does not work on Infura.
     filOpt := ⅋bind.FilterOpts{              ← Indicate start/end block
                 Context: ctx,
                 Start: 9000000,              ← Tune start/end to avoid DoS on node.
                 End: nil
               }
     itr, err := ctr.FilterDeposited(filOpt)  ← Filter"EventName" Autogenerated by 'abigen'
     for itr.Next() {
         event := itr.Event
         fmt.Printf(event.Addr.Hex())
     }
  └ listening for (FUTURE!!!) events: 
    watchOpts := ⅋bind.WatchOpts{
                    Context: ctx,
                    Start: nil
                 }
    channel := make(chan               ← STEP 1) Setup (async) channel for (FUTURE) results
       *coolcontract.CoolContractDeposited)
    go func() {                        ← STEP 2) Start goroutine listening for events
       sub, err := ctr.WatchDeposited( ← Watch"EventName" autogenerated by 'abigen'
          watchOpts, channel)
        defer sub.Unsubscribe()
    }()
    event := ˂-channel                 ← Receive events from channel

   TIP: to retrieve both historical and future events,
        create subscription goroutine BEFORE filtering old states.
        Wait for a bit so you’re certain it gets scheduled.
      RºWARN:ºotherwise you might loose events.

   └ parsing events from types.Log  (useful in some scenarios): (TODO)
     log := *new(types.Log)
     event, err := ctr.ParseDeposited(log)

 º========================================º
•ºTESTING (using go-ethereum as a library)º
 º========================================º
@[https://medium.com/coinmonks/intro-to-web3-go-part-4-5a21bc71fddc]
  low-code simulated blockchain for unit tests embedded in go-etherum.
  
  (accounts/abi/bind/backends/)backends.SimulatedBackend implement 
  ˂˂ContractBackend˃˃ (replacing ethclient.Client node connection).

  backend := backends.NewSimulatedBackend(
             core.DefaultGenesisBlock().Alloc,
             9000000)
  bal, err := backend.BalanceAt(
              ctx, common.HexToAddress("0x.."), nil)

  faucetSK, err := crypto.GenerateKey() 
  faucetAddr := crypto.PubkeyToAddress(faucetSK.PublicKey)
  addr := map[common.Address]core
       .GenesisAccount{
          common.BytesToAddress([]byte{1}): 
            {Balance: big.NewInt(1)}, // ECRecover   precompiles
          common.BytesToAddress([]byte{2}):
            {Balance: big.NewInt(1)}, // SHA256      precompiles
          common.BytesToAddress([]byte{3}):
            {Balance: big.NewInt(1)}, // RIPEMD      precompiles
          common.BytesToAddress([]byte{4}):
            {Balance: big.NewInt(1)}, // Identity    precompiles
          common.BytesToAddress([]byte{5}):
            {Balance: big.NewInt(1)}, // ModExp      precompiles
          common.BytesToAddress([]byte{6}):
            {Balance: big.NewInt(1)}, // ECAdd       precompiles
          common.BytesToAddress([]byte{7}):
            {Balance: big.NewInt(1)}, // ECScalarMul precompiles
          common.BytesToAddress([]byte{8}):
            {Balance: big.NewInt(1)}, // ECPairing   precompiles
          faucetAddr:
            {Balance: new(big.Int)
                      .Sub(new(big.Int)
                      .Lsh(big.NewInt(1), 256) ,
                      big.NewInt(9))
            },
       }
  alloc := core.GenesisAlloc(addr)
  backend := backends.NewSimulatedBackend(
          alloc, 9000000 /* gas limit*/)

  observations: All precompiles need to own some ether to remove 
                purging-account differences among nodes.

  BalanceAt/BlockByNumber/deploy+interact with contracts work as 
  ussual with ethclient.Client.

• Overwrite SendTransaction to behave like ethclient.SendTransaction:
  simulated blockchain allows for interesting scenarios:
  - By skipping Commit() after every transaction, TX-per-block 
    can be tunned.
  - Rollback() can abort all pending (not commited) transaction
    (simulate TXs dropped from TX pool).
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
web3.py
@[https://github.com/ethereum/web3.py]
Brownie
@[https://eth-brownie.readthedocs.io/en/latest/]
@[https://eth-brownie.readthedocs.io/en/stable/tests-hypothesis-property.html]
@[https://github.com/HyperLink-Technology/brownie]
- simple python framework for testing, deploying and interacting
  with ethereum smart contracts.


Property-Based Testing — Brownie v1.6.5 documentation

See Also:
- Effective Smart Contract Testing with Brownie:
@[https://medium.com/coinmonks/effective-smart-contract-testing-developer-revert-comments-c7a6f250df0f]
TextUI (Console Prototyping)
@[https://github.com/kayagoban/shadowlands]
- Python based, TextUI rapid prototyping platform for Eth apps which breaks
  the paradigm that everything must be a web app.
- Suppport BºTrezor Harwdware Walletº, .
Scalability

• Layer 1 Scalability Solutions include:
  · DDBB (storage) Sharding.
  · Multi-signature aggregation.
    (e.g.: EIP-191: Signed Data  Standard,...)
  · EVM improvements.
  · eWASM runtime.
 
• State channels:
  · Account-to-Account offchain state channel periodically 
    synchronized within MainNet. Ussually the state reflects 
    the balance of two peer accounts, but it could be 
    anything else. It highly increases the TX/sec by offloading 
    as much TX as desired from main network, but requires
    collaboration and monitoring by both peers.

• Layer 2 Rollups Scaling:
  · "Children" networks protected by MainNet.
  · Many different methods exist to sync with MainNet,
• Layer 2 Side chain Scaling:
  · Similar to L2 Rollups with with lower security. 
    They "sync" to L1 through peer "escrow" contracts on each
    network (L1 and L2) in charge of syncrhonizing escrows.
    They can use more centralized consensus (consortium IBFTv2, 
    ...).
    Rollups require L2 each block update to be "notarized" (optimistic
    rollups) or probed (zk-rollups). Side-chains can "sync" at 
    will every N blocks.
    "sidechain" term is often used to imply that an INDEPENDENT
    blockchain has a relationship with another blockchain.
  · bridge contracts types can be divided into:
    · Single organisational: 1        owner  custody locked funds in escrow.
    · Multi organisational : N-of-M   owners custody locked funds in escrow.
    · Crypto-economic      : "moving" owners custody locked funds in escrow
                             relative to the weight of their assets.

Rollups (L2 Scaling) • As of 2021, optimistic rollups (bundling L2-chain blocks) is the working solution. In a near future zk-Rollups will "replace" them: • optimistic-Rollups provide passive security while zk-Rollups provide active security. • optimistic-Rollups need to submit a "zipped" version of data to L1 blockchain whileºzk-Roolupsºhave to potential to send only a proof of the full block allowing for theorical performance upgrades of ºtens of thousands TX/s.º • zSNARKS provides also for enhanced privacy. (but scalability features are even more important). • optimistic-Roolups are more compatible with Layer 1 "MainChain". zk-SNARKs L2 chains require new signatures schemas not compatible with L1, requiring also changes in wallets (Metamask,...) to avoid the need of intermediate "custom" DApp wallets. Scalability L2 Comparation: REF: @[https://www.youtube.com/watch?v=qwtOJvFo6vs] ┌─────────┐ │ Honesty │← Active Security. │ Proofs │ No false transitions can be submitted. └────┬────┘ ├ ZKP (zk-Rollups: Validium, 0x, ...) │ ├ Sign.Aggregation │ │ │ Merkle ┌────────┐ Compression │ Trees ZKP ┌─────────┐ │ Data │──────┴─────┬────┼───┬──────┴────┬──┴──│ Data │ │On Chain│ Gas │Acummulators VC │Off-Chain│ └────────┘ golfing │ └─────────┘ ├ Rollback ├ Slashing │ ├ Optimistic Rollups/Watch-Towers: monitoring TXs. │ W.T can fail but they can compete with each other │ e.x.: Plasma, Optimistic, ... │ ┌───┴────┐ │ Fraud │← Passive Security. Fix problem after detection. │ Proofs │ All TX are accepted as valid and Watch-Towers └────────┘ need to probe the opposite. • Accumulators can only test "SET membership". • Merkle trees improve over accumulators by having an "index" that can be mapped to a balance. • Factors commitments mix the advantages of accumulators and Merklet trees. • ZKP improves all over the previous techniques (Accumulators/Merkle Trees, ...)
Zokrates @[https://zokrates.github.io/print.html] @[https://www.youtube.com/watch?v=YymE69JcKEk] [Video] - Convert zSNARKS "algebra" circuits to Solidity verifier code. - Clients can send "proofs" to be verified by the Solidity code that will ultimately continue/rollback any TX.
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
 - 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│ - once a block on the beacon chain is finalised,
  shards through cross-links        │   the shard blocks referenced in the included
                                    │   crosslinks are considered finalised
                                    │ - each shard has a committee of validators
                                    │   attesting blocks
                                      ^
                           @[https://blog.ethereum.org/2020/03/27/sharding-consensus/]
ºCROSSLINKSº                   │ºSLOTº                           │ºEPOCHº
 - summary of the shard's state│ period of time in which a block │ a number of slots(64 "now")
 - only reference of the shards│ proposer propose a block for    │ after which validators are
   in the beacon chain         │  attestation                    │ reshuffled in committees
                               │ - slots might be empty          │
                               │ - slots are filled with attested│
                               │   blocks                        │

ºVALIDATORSº                                   │ºBLOCK PROPOSERSº
 - users that have deposited 32th 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  │ ─ random groups of validators     │ ─ base currency of beacon chain
   validity of a shard block│   chosen by the beacon chain to   │ ─ will be obtained initially
   or beacon                │   attest the validity of blocks   │   from rewards and by locking
                            │   (beacon+shard)                  │   ETH1 in the validator deposit
                            │ ─ target of minimum 128 validators│   contract
                            │   per 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


BºIstambul Bizantine Fault Tolerant(IBFT)º
@[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.

ºROUNDº                                      ºROUND STATEº
Consensus round. A round starts with         Consensus messages of a specific
the proposer creating a block proposal       sequence and round, including
and ends with a block commitment or          pre-prepare message, prepare message,
round change.                                and commit message.

ºPROPOSALº                                ºSEQUENCEº
New block generation proposal which is    Sequence number of a proposal. A
undergoing consensus processing           sequence number should be greater than
                                          all previous sequence numbers.
                                          Currently each proposed block height is
                                          its associated sequence number.

ºBACKLOGº                                 ºCONSENSUS PROOF:º
The storage to keep future consensus      The commitment signatures of a block
messages due to the async nature of the   that can prove the block has gone
network.                                  through the consensus process.

ºSNAPSHOT:º
The validator voting state from last
epoch


Bº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º


Bº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

BºISTANBUL OPTIONS:º
  --istanbul.requesttimeout value  round in milliseconds (default: 10000)
  --istanbul.blockperiod    value  Default min.difference between two consecutive
                                   block's timestamps in seconds (default: 1)

BºNODEKEY AND VALIDATORº
  To be a validator, a node needs to meet the following conditions:
  - Its account (nodekey-derived) address MUST be listed in extraData's validators section
  - validator nodekey is used as priv.key to sign consensus messages

BºEncoding:º
  Before encoding you need to define a toml file with vanity and validators fields
  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º

BºDecoding:º
  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º

Bºgenesis.jsonº
  - config field is required, and the pbft subfield must present. Ex:
  - See also genesis.json helper tools at:
  @[https://github.com/getamis/Istanbul-tools]
  {
    "config": {
      "chainId": 2016,
      "istanbul": { "epoch": 30000, "policy" 0 }
    },
    "timestamp": "0x0",
    "parentHash": "0x000...000",
    "extraData": "0x0000...000f89af85494475...aad0312b84100000...0c0",
    "gasLimit": "0x47e7c4",
    "mixhash": "0x6374...6e6365",
    "coinbase": "0x333...33333",
    "nonce": "0x0",
    "difficulity": "0x0",
    "alloc": {}
  }
Casper PoS (Ethereum 2)
PoS: Proof-of-Stake:
@[https://consensys.net/blog/blockchain-explained/what-is-ethereum-2/]
- Reducing mining hardware requirements and scalates TX/s.
- Consensus continues to have eventual transaction finality.
  (mined transactions can appear and dissapear and we need to wait
  for N blocks to have statistical confirmation).

-  PoW             PoS
   miners       →  validators
   electricity  →  stake

"MINING":
 validator → deposit SC : commit 32 ETH as "skin in the game"
            º*1º          into the official deposit contract
 ...
 network → network      : randomnly select new validator
                          to propose and attest to blocks
 validator → network    : correctly propose and attest to blocks
 network → validator    : reward

º*1º Ethereum Foundation Eth2 deposit contract:
     https://github.com/ethereum/eth2.0-specs/tree/dev/deposit_contract

- if a validator fails to stay online and execute their share of
  computational responsibilities, block reward will moderately decrease 
  as to incentivize validators to stay online.

 - Byzantine validators trying to compromise the network
   (i.e. validate incorrect data history), will be punished
   with some/all of their 32 staked ETH.

 - In order for the beacon chain to launch its genesis block,
   at least 524,288 ETH must be staked on the network, divided
   among a minimum of 16,384 validators (these numbers were decided
   upon to ensure sufficient security and decentralization).
 - Staking rewards will not be distributed until this threshold
   is reached, which is partially why some altruistic behavior is
   needed among the early participants in phase 0.

 RºWARN:ºbeacon chain will not be particularly useful to the majority
         of Ethereum users inRºPhase 0º;
         - it will be unable to process transactions, execute smart
           contracts, or host dapps.
         BºThis is by designº, ensuring Proof of Stake undergoes
           considerable testing as a live, functioning network before
           dapps and users begin transacting by the millions on a
           daily basis.

  Phase 0:
  - Original Ethereum 1.0 blockchain will continue to run
    in parallel and receive upgrades during Phase 0.

  Phase 1:
  - Implementation of shard chains.
  - Ethereum will be partitioned into 64 separate (shard) chains,
    coordinated by a beacon chain.

  Phase 1.5:
  - merging of the original PoW Ethereum with PoS chain.
    It will be brought into Ethereum 2.0 and exist as one
    of the 64 shard chains alongside the beacon chain
    with no break in continuity or data history.
    - ETH holders will not have to undergo any sort of
      token transfer or swap between Ethereum 1.0 and 2.0.

  Phase 2:
  - currently (2020-05) less defined.
    Enable ether accounts, transactions, transfers and withdrawals,
    and smart contract execution.


polygon.Network
@[https://polygonscan.com/]
• Polygon solves pain points associated with Blockchains, like high gas 
  fees and slow speeds, without sacrificing on security. This 
  multi-chain system is akin to other ones such as Polkadot, Cosmos, 
  Avalanche etc, but with at least three major upsides:

  + It is able to fully benefit from Ethereum’s network effects
  + It is inherently more secure
  + It is more open and powerful

• Polygon is both a protocol and a framework for building and connecting
  Ethereum-compatible blockchain networks, featuring:

  + One-click deployment of preset blockchain networks
  + Growing set of modules for developing custom networks
  + Interoperability protocol for exchanging arbitrary messages with Ethereum 
    and other blockchain networks
  + Modular and optional "security as a service".
  + Adaptor modules for enabling interoperability for existing blockchain networks.

• See POLYGON (MATIC) - Ethereum's Internet Of Blockchains Explained - Layer 2 [Video]
@[https://www.youtube.com/watch?v=IijtdpAtOt0%20%20POLYGON%20(MATIC)%20-%20Ethereum%27s%20Internet%20Of%20Blockchains%20Explained%20-%20Layer%202]

• TODO: Looks like different Polygon networks can connect
        through side-chains or rollups.
  extracted from https://blog.infura.io/offchain-protocols-sidechains-and-rollups/ 
  "... Polygon side-chain uses a crypto-economic bridge ... 
        (⅔)+1 of stake to appoint validators who post periodic
        checkpoints about network's state to bridge contract  ..."
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/ Minimal Viable Plasma @[https://ethresear.ch/t/minimal-viable-plasma/426]
Lead DAO
@[https://leapdao.org/]
- More Viable Plasma design with smart contract like functionality.
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)|
                                                          +-------------------+

NOTE: private (node-to-node) eea TX can NOT be used to prevent double-spending:
      only for notarization like (ballots, ...) use-case scenarios were there will 
      probably be a "controller node" to wich all information arrives, (even if it's
      just partially visible to other nodes):
    @[https://stackoverflow.com/questions/56906115/private-transaction-validation-in-quorum]
      To prevese privacy and double-spending, Zero Knowledge Proofs must be used.
____________________________________________________________________________________________

º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://github.com/apache/camel/blob/main/components/camel-web3j/src/main/docs/web3j-component.adoc]
@[https://medium.com/@bibryam/enterprise-integration-for-ethereum-fa67a1577d43]

• Sample 1: Listen for new mined blocks and send the block hash to 
             a jms queue:

  from("web3j://http://127.0.0.1:7545?operation=ETH_BLOCK_HASH_OBSERVABLE")
      .to("jms:queue:blocks");

• Sample 2: Use block hash code to retrieve the block and full TXs details:
  from("jms:queue:blocks")
    .setHeader(BLOCK_HASH, body())
    .to( "web3j://http://127.0.0.1:7545?"
       + "operation=ETH_GET_BLOCK_BY_HASH⅋"
       + "fullTransactionObjects=true");

• Sample 3:
  from("direct:start")
    .to("web3j://http://127.0.0.1:7545?"
      + "operation=ETH_GET_BALANCE⅋"    ← Read balance
      + "address=0xc8CDce..⅋"             ← for address 
      + "atBlock=10");                    ← at given block


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.
Vue+Eth+IPFS
@[https://github.com/redacademy/vue-ethereum-ipfs]
  Distributed Application Starter:
- Vue front-end, Ethereum / IPFS Backend
External Inputs (Oracles)
• The evm and SmartContract by extension just have access to 
  internal (current-state) blockchain data. Oracles are used when we 
  need logic that depends of external-to-blockchain events, playing the 
  role of "input" devices.
• Oracles in practice are "trusted" smart-contracts whose internal data/status
  is the result of a list of minimum threshold "N" of "M" different Signatures,
  or some sort of voting. Each signature can have a different reputation/weight.
• For example we trust a deployed Oracle that claims that a vehicle 
  with ID:ABCDEF had an accident because map( hashOfCAR_ID =˃ 
  carStatus) ddbbStatus is updated only after at least N signatures of 
  M trusted signers have been sent claiming such accident is true.

• Companies like ChainLink offer "professional oracle services for MainNet 
  and other networks.


chain.link Oracles • "Pole position" in Secutiry Dapps in @[https://www.stateofthedapps.com/] with 1.700+ votes. • @[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,
Provable.xyz Oracles https://provable.xyz/ The ProvableTM blockchain oracle for modern DApps. Enabling the shift of traditional services such as finance, gambling, and insurance into decentralization.
band-protocol @[https://bandprotocol.com/] • Band Protocol is a cross-chain data oracle platform that aggregates and connects real-world data and APIs to smart contracts.
 Whisper Dapp Protocol
@[https://github.com/ethereum/wiki/wiki/Whisper]
- 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
- 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+, Besu 1.2+, and others)
  OºEthQL has the potential to avoid the sync from blockchain to aº
  Oºconventional SQL database for creating reports.º

BºExample GraphQL Queriesº
@[https://github.com/ConsenSys/ethql/wiki/Example-Use-Cases]
  ºQuery a single block (5000000)º
[fiddle]
BºExample Queryº
  {                                                   QUERY:
    block(number: Bº5000000º) {                     ← SELECT ... FROM block 5000 ...
      hash                                                    ^                   ^
      transactions                                  ← transactions                ·
        (filter: Oº{ withInput: true }º)            ← WHERE input Data existsº ····

      {                                             ← SUBQUERY OVER QUERY RESULTS:
                                                      SELECT ... FROM FIRST_QUERY
        index                                                                      ^
        hash                                                                       ·
        from { address }                              WHERE from=address AND to=address
        to   { address }
      Qºdecoded {º
      Qº  ... on ERC20Transfer {                    ← for those that can be decoded as º
      Qº                                              token transfers, return.º
      Qº    tokenContract { symbol }                  ← token symbolº
      Qº    from {                                    ← sending addressº
      Qº      account { address }º
      Qº      tokenBalance                            ← sending address token balanceº
      Qº    }º
      Qº    to {  account { address } }               ← receiving addressº
      Qº    valueº
      Qº  }º
      Qº}º
      }
    }
  }

BºInformation on specific blocksº
  {
    blocks(numbers: [1000, 1001,])   {        ← SELECT ... FROM BLOCK in (1000,1001)
                                                       ^
      transactionsRoles(from:"0xF5b...") {    ← transactions.gasPrice WHERE from = 0xF5b...
        gasPrice   ←···········································┘
      }
    }
  }

BºInformation on a range of blocksº
  {
    blocksRange(numberRange: [54000, 54005])   ← SELECT ... FROM BLOCK in numberRanger
    {                                                   ^
                                                        └··········┐
      transactions {                                               │
        hash                                      tx.hash  ········┤
        value                                     tx.value ········┤
        from {                                                     │
          address                                 tx.from.address··┤
          balance                                 tx.from.balance··┤
        }                                                          │
        to { address }                            tx.to  .address··┘
      }
    }
  }

BºInformation on an accountº
  for account "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d".
  {                                 ← SELECT ... FROM BLOCKCHAIN   ...
                                              ^                     ^
                                              ·    ┌────────────────┴──────┐
   account(address: "0x06012..."){            ·  ← WHERE account="0x6012..."
     storage{                                 ·
       value(at: 0)                   account.storage.value at index 0
     }
   }
  }

Bº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 over HTTP @[https://besu.hyperledger.org/en/stable/HowTo/Interact/APIs/GraphQL/] - Reduce overhead for common queries. Ex: Non-GraphQL GraphQL: ---------------------- ------------------ - query Rºeach receiptº - single query for in a block - The Besu GraphQL schema describes the GraphQL implementation for Ethereum. Enable the GraphQL service using command line options. Note GraphQL is not supported over WebSockets. Access the GraphQL endpoint at http://:/graphql. Configure and using graphql-http-host and graphql-http-port. The default endpoint is http://127.0.0.1:8547/graphql. GraphQL requests with cURL Hyperledger Besu JSON-RPC API methods with an equivalent GraphQL query include a GraphQL request and result in the method example. Example The following syncing request returns data about the synchronization status. curl -X POST -H "Content-Type: application/json" \ --data '{ "query": "{syncing{startingBlock currentBlock highestBlock}}"}' http://localhost:8547/graphql GraphQL requests with GraphiQL App The third-party tool, GraphiQL, provides a tabbed interface for editing and testing GraphQL queries and mutations. GraphiQL also provides access to the Besu GraphQL schema from within the app. Besu does not execute pending transactions so results from account, call, and estimateGas for Pending do not reflect pending transactions. Example Pending Transaction Count curl -X POST -H "Content-Type: application/json" \ --data '{ "query": "{pending {transactionCount}}"}' \ http://localhost:8547/graphql Pending Transactions curl -X POST -H "Content-Type: application/json" \ --data '{ "query": "{pending {transactions{hash}}}"}' \ http://localhost:8547/graphql
TheGraph Protocol
• "Before The Graph, teams had to develop and operate proprietary 
  indexing servers. This required significant engineering and hardware 
  resources and broke the important security properties required for 
  decentralization."

• TheGraph can be part of Sharding scalability future:
@[https://money.yahoo.com/graph-positioned-unshackle-ethereum-2-180403603.html]
  "...  Vitalik’s idea is effectively ‘rollups on top of 
   sharding’, but this creates its own issue – where will the 
   historical data from all these shards be stored? 

   ...problem: where exactly all this sharding data go?
   Vitalik suggested institutional volunteers, DAOs, block
   explorers, and torrents as theoretical solutions – but only
  one project was name-dropped:
 º Protocols like The Graph can create incentivised marketplaces º
 ºwhere clients pay servers for historical data with Merkle proofs of º
 ºits correctness.  This creates an incentive for people and º
 ºinstitutions to run servers that store historical data and º
 ºprovide it on demand.º

• popular services already using TheGraph protocol:
  Uniswap:
  Sintetics:
  Decentraland:
  Aragon:

• TODO:
@[https://thegraph.com/docs/developer/create-subgraph-hosted] 
@[https://medium.com/intech-conseil-expertise/create-your-graph-node-to-query-complex-data-from-blockchain-via-graphql-6f08fbd494c5]

By Kebin Thizy
- GitHub repo: @[https://github.com/investorid/subgraph-experiment]

- º"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.”                            º

•ºit knows about the entities it indexes.º
  composed of subgraphs, carefully developed by the community.
• There is a global instance of TheGraph that accepts subgraph definition.

BºExample reference Smart Contract storing Identity claimsº
   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
   ...
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ºFor each contract instance, for each claim type, º
  ºfetch all claims attested/signed by same issuer_iNº

  └ Without Graphs:
    for contract in identityContractInstances:     ← RºA loop for each instanceº
       for claim_type in type1 type2 ...:          ← RºA loop for each type    º
           fetch claims where issuer = issuer_iN
  └ With GraphQL and the Graph protocol:
  -GºA single GraphQL query sufficesº.

-ºPRE-SETUPº(opinionated, using docker, and NodeJS)
  - $ git cloneºhttps://github.com/graphprotocol/graph-node.gitº
    $ cd graph-node
    $ sudo docker-compose up # ← Start up Graph instance/PostgreSQL/IPFS
                                 needs ports 4001, 5001, 8000, 8001, 8020,
                                             8080 and 5432

  - $ 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)
BºCreating the Graph:º

 Bºsubgraph.yamlº: meta-data describing the SubGraph:
                   Declares ABI to be used and scanned
                   by the graph node.
   | specVersion: 0.0.3
   | description: Decentralized IDs over Ethereum
   | repository: https://github.com/investorid/investorid-subgraph
   | schema:
┌→ |   file: ./schema.graphql    ← entities used by the SubGraph and exposed via GraphQL.
·  | 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:   ←················· Any entity used by event handlers
·  |         - Identity                   must be declared in here
·  |         - Key
·  |       abis:
·  |         - name: Identity
·  |           file: ./node_modules/@investorid/solidity/build/contracts/Identity.json
·  |       eventHandlers: ←·············· all event to be scanned/handled must
·  |                                      be declared here
·  |         - event: KeyAdded(indexed bytes32,indexed uint256,indexed uint256)
·  |           handler:QºhandleKeyAddedº
·  |         - event: KeyRemoved(indexed bytes32,indexed uint256,indexed uint256)
·  |           handler:QºhandleKeyRemovedº
·                                  ·
└Bºschema.graphqlº
   | type Identity @entity {
   |   id: ID!
   |   address: Bytes!
   |   keys: [Key!]! @derivedFrom(field: "identity")  ← reverse property
   | }                                                  more info at:
   |                                                  @[https://thegraph.com/docs/graphql-api]
   | type Key @entity {
   |   id: ID!
   |   keyType: BigInt!    ← BigInt, Bytesis a custom type
   |   key: Bytes!
   |   purposes: [Int!]!
   |   identity: Identity!
   | }

 Bº.src/handlers/identity.tsº ← Event handlers:
                                To generated the referenced typings and
                                automated code parts referenced run
                                $ yarnºrun codegenº
                                ouput:
                                → ../../generated/Identity/Identity
                                → ../../generated/schema

  | 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
  |        Qº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
  |        Qº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());
  | }

BºImplementation of event handlersº
  Refer to The Graph documentation, to learn how to write mappings.

  - basics about mappings:
    - To create a new entity instance, call:
      ˂Entity˃#create(˂id˃)  ← ˂id˃ 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:
      ˂Entity˃#load(˂id˃)
    - To save new entity|update existing one, call:
      ˂entity˃.save()
    - To destroy and remove an entity from the store, call
      store.remove('EntityName', id)

BºRunning the subgraphº

  $ yarn run build        ←·· Build SubGraph
  $ yarn run create-local ←·· Declare it  on local Graph node
  $ yarn run deploy-local ←·· Deploy  to the local Graph node
  $ yarn run watch-local  ←·· Optional: Watch deployig after
                                      each code update


  GraphQL UI for queries available at:
  http://127.0.0.1:8000/subgraphs/name/domain/graph-name/graphql
                                       └──────┬────────┘
                                       replace with name
                                       of the subgraph

Note: Whenever the Ethereum network has been reseted
      (Ganache restarted,...), the ./docker/data must
      be deleted:
      - required to clean the existing database
        that checks the genesis block for the
        current ethereum network.
AWS Lambda → Eth.RPC
@[https://blogs.sequoiainc.com/blockchain-dev-part-2-ethereum-rpc-from-aws-lambda/]
  how to interact with that node via RPC using an AWS Lambda function. This
  enables DApp development to leverage benefits of "serverless" software
  architecture while still maintaining the isolation and security of our original
  architecture.
Kaleido.io
- @[https://kaleido.io/]: SaaS Ethereum/Quorum in AWS, Azure, ...
  - Marketplace: @[https://marketplace.kaleido.io/]
    - Salesforce Integration    : 
    - 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            [privacy]


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
Understanding Geth Code
 @[https://github.com/Agzs/geth-pbft-study/wiki/Blockchain-Structure]

  typeºBlockChainºstruct {
    config *params.ChainConfig // chain & network configuration

┌   hc           *HeaderChain
|   chainDb      ethdb.Database
|   eventMux     *event.TypeMux
|   genesisBlock *types.Block
|
|   mu      sync.RWMutex // global mutex for locking chain operations
|   chainmu sync.RWMutex // blockchain insertion lock
|   procmu  sync.RWMutex // block processor lock
|
|   checkpoint       int          // checkpoint counts towards the new checkpoint
|┌  currentBlock     *types.Block // Current head of the block chain
|·  currentFastBlock *types.Block // Current head of the fast-sync chain (may be above the block chain!)
|·
|·  stateCache   state.Database // State database to reuse between imports (contains state cache)
|·  bodyCache    *lru.Cache     // Cache for the most recent block bodies
|·  bodyRLPCache *lru.Cache     // Cache for the most recent block bodies in RLP encoded format
|·  blockCache   *lru.Cache     // Cache for the most recent entire blocks
|·  futureBlocks *lru.Cache     // future blocks are blocks added for later processing
|·
|·  quit    chan struct{} // blockchain quit channel
|·  running int32         // running must be called atomically
|·  // procInterrupt must be atomically called
|·  procInterrupt int32          // interrupt signaler for block processing
|·  wg            sync.WaitGroup // chain processing wait group for shutting down
|·
|·  engine    consensus.Engine
|·  processor Processor // block processor interface
|·  validator Validator // block and state validator interface
|·  vmConfig  vm.Config
|·
|·  badBlocks *lru.Cache // Bad block cache
|·}
|·
|·                                                 // Header represents a block header in the Ethereum blockchain.
|└→typeºBlockºstruct {                             typeºHeaderºstruct {
|    header       *Header ·······················→  ParentHash  common.Hash    Keccak256(parent_block_header)
|    uncles       []*Header                         UncleHash   common.Hash
|    transactions Transactions                      Coinbase    common.Address miner address
|                                                   Root        common.Hash   ← of state    trie
|    // caches                                      TxHash      common.Hash   ← of TX       trie
|    hash atomic.Value                              ReceiptHash common.Hash   ← of receipts trie
|    size atomic.Value                              Bloom       Bloom
|                                                   Difficulty  *big.Int
|    // Td is used by package core to store the     Number      *big.Int
|    // total difficulty of the chain up to and     GasLimit    *big.Int
|    // including the block.                        GasUsed     *big.Int
|    td *big.Int                                    Time        *big.Int
|                                                   Extra       []byte
|    // These fields are used by package eth        MixDigest   common.Hash
|    // to track inter-peer block relay.            Nonce       BlockNonce    ← PoW (Combined with
|    ReceivedAt   time.Time                       }                             MixDigest)
|    ReceivedFrom interface{}
|  }
|
└→ typeºHeaderChainºstruct {
       config *params.ChainConfig

       chainDb       ethdb.Database
       genesisHeader *types.Header

       currentHeader     *types.Header // Current head of the header chain (may be above the block chain!)
       currentHeaderHash common.Hash   // Hash of the current head of the header chain (prevent recomputing all the time)

       headerCache *lru.Cache // Cache for the most recent block headers
       tdCache     *lru.Cache // Cache for the most recent block total difficulties
       numberCache *lru.Cache // Cache for the most recent block numbers

       procInterrupt func() bool

       rand   *mrand.Rand
       engine consensus.Engine
   }


BºTRANSACTIONSº
  typeºTransactionºstruct {    typeºtxdataºstruct {
      data txdata                  AccountNonce uint64          `json:"nonce"    gencodec:"required"`
      // caches                    Price        *big.Int        `json:"gasPrice" gencodec:"required"`
      hash atomic.Value            GasLimit     *big.Int        `json:"gas"      gencodec:"required"`
      size atomic.Value            Recipient    *common.Address `json:"to"       rlp:"nil"` // nil → new contract
      from atomic.Value            Amount       *big.Int        `json:"value"    gencodec:"required"`
  }                                Payload      []byte          `json:"input"    gencodec:"required"`

                                   // Signature values
                                   V *big.Int `json:"v" gencodec:"required"`
                                   R *big.Int `json:"r" gencodec:"required"`
                                   S *big.Int `json:"s" gencodec:"required"`

                                   // This is only used when marshaling to JSON.
                                   Hash *common.Hash `json:"hash" rlp:"-"`
                               }

BºDATABASEº
  typeºDatabaseºinterface {
      Put(key []byte, value []byte) error
      Get(key []byte) ([]byte, error)
      Delete(key []byte) error
      Close()
      NewBatch() Batch
  }
  //==> Implied by LDBDatabase ==>
  typeºLDBDatabaseºstruct {
      fn string      // filename for reporting
      db *leveldb.DB // LevelDB instance

      getTimer       gometrics.Timer // Timer for measuring the database get request counts and latencies
      putTimer       gometrics.Timer // Timer for measuring the database put request counts and latencies
      delTimer       gometrics.Timer // Timer for measuring the database delete request counts and latencies
      missMeter      gometrics.Meter // Meter for measuring the missed database get requests
      readMeter      gometrics.Meter // Meter for measuring the database get request data usage
      writeMeter     gometrics.Meter // Meter for measuring the database put request data usage
      compTimeMeter  gometrics.Meter // Meter for measuring the total time spent in database compaction
      compReadMeter  gometrics.Meter // Meter for measuring the data read during compaction
      compWriteMeter gometrics.Meter // Meter for measuring the data written during compaction

      quitLock sync.Mutex      // Mutex protecting the quit channel access
      quitChan chan chan error // Quit channel to stop the metrics collection before closing the database

      log log.Logger // Contextual logger tracking the database path
  }

  // Database wraps access to tries and contract code.   //==> Implied by cachingDB ==>
  typeº(state.)Databaseºinterface {                      typeºcachingDBºstruct {
      // Accessing tries:                                    db            ethdb.Database
      // OpenTrie opens the main account trie.               mu            sync.Mutex
      // OpenStorageTrie opens the storage trie              pastTries     []*trie.SecureTrie
      // of an account.                                      codeSizeCache *lru.Cache
      OpenTrie(root common.Hash) (Trie, error)           }
      OpenStorageTrie(addrHash, root common.Hash)
         (Trie, error)
      // Accessing contract code:
      ContractCode(addrHash, codeHash common.Hash)
         ([]byte, error)
      ContractCodeSize(addrHash, codeHash common.Hash)
         (int, error)
      // CopyTrie returns an independent copy of
      // the given trie.
      CopyTrie(Trie) Trie
  }

  // Trie is a Ethereum Merkle Trie.           //==> Implied by odrTrie, SecureTrie, Trie,
  typeºTrieºinterface {                        // but implied by cachedTrie in this place.==>
      TryGet(key []byte) ([]byte, error)       // cachedTrie inserts its trie into a cachingDB
      TryUpdate(key, value []byte) error       // on commit.
      TryDelete(key []byte) error              typeºcachedTrieºstruct {
      CommitTo(trie.DatabaseWriter)                *trie.SecureTrie
         (common.Hash, error)                      db *cachingDB
      Hash() common.Hash                       }
      NodeIterator(startKey []byte)
          trie.NodeIterator
      GetKey([]byte) []byte // TODO(fjl):
               // remove this when SecureTrie
               // is removed
  }
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

BºSync Mode:º
  @[https://medium.com/coinmonks/how-a-pruned-ethereum-node-can-fully-verify-the-blockchain-bbe9f29663ed]
  @[https://github.com/ethereum/go-ethereum/pull/1889]

     Mode      2020
     Archive ~ 1.5TB -Contains state at all given blocks.
     Prune   ~ 0.2TB -Contains all events and just last state.
                      After synced, the node will continue to
                      work in Archive mode. It's recomended then
                      to resyn every ~6 months to save space unless
                      archive of old states are needed.

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.     º
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
Release Notes
1.9
@[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!)º                                     [wallet.cloud]
- standalone signer for the entire Ethereum ecosystem
- major features:
  - remove account management from maybe "insecure" Geth gateway.
  - Reusable by 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 aiming to be          [consensus.*]
  (security like) midway between trusted and light enodes.
-ºreplaces PoW verification with digital signatures from majority-of-trusted enodes:º
 ºultra light client mode is not really meant for an average node,º
 ºbut for projects embedding Geth into their own process.º

ºCHECKPOINT ORACLEº
 - Light clients use a hard coded checkpoint (vs verifying each header from block 0) 
   as starting point. This checkpoint contains all the necessary
   info to cryptographically verify even past headers, so security wise
   nothing is lost. Some shortcomings:
   -  hard coded into release binaries means older releases will always start
      syncing from an older block.
   -RºCan NOT be used in private networks.º
 -ºGeth v1.9.0 supports for on-chain checkpoint oracle.º
   light clients can reach out to untrusted remote light enodes and ask them to
   return an updated on-chain checkpoint stored within an on-chain smart contract,
   then cryptographically prove that returned data was signed by a required
   number of approved signers!
   - Geth ships with hard coded checkpoint oracle addresses and lists of authorized 
     signers to let light-enodes know who's authorized the checkpoint.
   BºPrivate networks can define oracle details 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 \ º   can also be used to deploy/sign checkpoints
   $º    status                               º
     Oracle =˃ 0xebe8eFA441B9302A0d7eaECc277c09d20D684540

     Admin 1 =˃ 0xD9C9Cd5f6779558b6e0eD4e6Acf6b1947E7fA1F3
     Admin 2 =˃ 0x78d1aD571A1A09D60D9BBf25894b44e4C8859595
     ...

º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.
EEA
  EEA Summary
• External resources:
  • @[https://entethalliance.org/]
  • @[https://github.com/EntEthAlliance/]
  • @[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]



[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,
     Besu, and EthereumJS."""

- RAFT:
- IBFT: (Istambul) Bizantine Fault Tolerant
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 Tessera (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]
Caliper(Benchmarks)
@[https://github.com/hyperledger/caliper] with support for:
- blockchain performance benchmark framework.
  test different blockchain solutions with predefined use cases,
  and get a set of performance test results.
  Currently supported blockchain solutions:
  - Hyperledger Fabric v1.X
  - Hyperledger Sawtooth 1.0+
  - Hyperledger Iroha 1.0 beta-3
  - Hyperledger Burrow 1.0
  - Ethereum
  - Hyperledger Besu, utilizing the Ethereum adapter.
  - FISCO BCOS
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_secp256k1 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]
- Sign TX and data (data "==" swap/swarm).
-  meant as a (eventual) replacement for Geth's account management.
   This allows DApps to not depend on Geth's account management.
   DApp send data/TX 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.
REF: @[https://hackmd.io/@ethswarm/SyrP04XdI] (2020-04)
-Rºlooks deadº but some work is happening again
  (https://github.com/ethereum/clef-ui).
- documentation is unclear on what works but testing
  showed it works surprisingly well
-Bºcan sign arbirtrary dataº
- simple JS rules can allow automatic signing of
  TX and cheques with constraints.
- seems to have quite a few Rºundocumented featuresº
- only allows function signatures from the 4bytes directory
  (swap was not yet there)
-Bºgo-ethereum already has code for using clef as a signerº
-Bºmanaged to deploy chequebooks and sign chequesº:
 @[https://github.com/ralph-pichler/swap-clef-test]

-RºTightly integrated with gethº. Adding any crypto functions
  requires modifying the main go-ethereum wallet interface
  - modify keystore backend.
  - modify the hw wallet and smart card backends


EthSigner 
REF: @[https://hackmd.io/@ethswarm/SyrP04XdI] (2020-04)
     @[https://docs.ethsigner.pegasys.tech/en/latest/]
  - used as backend, replaces eth_sendTransaction (similar in usage to metamask)
  - does not replace eth_signData (and alike)
  - hacks for eth_signData seem possible (based on blog posts),
    but even that Rºdoesn’t allow arbitrary dataº
  - does not work well with the design of go-ethereum based
    contract interaction
  - primarily for enterprise (Azure Key Vault, Hashicorp,...)

        eth_sendTransaction/    eth_sendRawTransaction/
        eea_sendTransaction     eea_sendRawTransaction
                 |                    |
                 ↓                    ↓
    │Dapp│     ←····→ │EthSigner│ ←······→ │Ether │
    (Web3j/            Signs TXs           │Client│
    Web3j-eea)           ↑
                         |
                         ↓
                     │─ V3 Keystore    │
                     │─ Hashicorp Vault│
                     │─ Azure Key Vault│
Privacy layers
└ Privacy of participants:
  Allow for anonymous parties.
  - on-chain cryptographic mechanisms
    like ring signatures, stealth addresses, mixing,
    or storage of private data off-chain.
└ Privacy of data:
  keep transactions, balances, smart contracts,
  and other data encrypted on or off chain, with
  cryptographic tools like zero-knowledge proofs
  and zk-SNARKS, Pedersen commitments, or off-chain
  privacy layers like TEEs.
  └ Consensys Project Ubin:
    - Public TX validated by the whole network but whose
      amount, asset type,... are shielded.
      "...a consortium of financial institutions used
        zero-knowledge proofs to enable the transfer of digital assets on a
        distributed ledger without revealing information about the balances
        or TX amounts"
    - Project Khokha (South African Reserve Bank "PoC")
      Pe commitments are also additively homomorphic, which means that
      for a balance update, network participants can validate that the correct
      update has happened without knowing the opening balance, the closing
      balance, or the transfer amount.
    - Pedersen commitments and Folklore range proofs to process the typical
      daily volume of payments for the SARB with full confidentiality and
      finality in less than two hours. These commitment schemes proved to be
      much quicker to validate than the zero-knowledge proofs.
    - Adhara has been exploring substituting range proofs with bullet proofs,
      which are much smaller and quicker to validate. Very simply, instead
      of writing the balances and the transaction amounts in the clear as in
      a normal ERC20 contract, nodes write a proof or a Pedersen commitment
      of the balance.
└ Public-First + Privacy Layers = Future-Proof
  - Business networks need resilience, interoperability, permissioning,
    and privacy to succeed.

"...These requirements, however, are out of scope for proprietary distributed
ledgers, let alone traditional database technologies. The Ethereum
granular privacy layers and public-first approach make it a powerful
enterprise solution for organizations that need the flexibility of an in-
house platform and that want the global reach to participate in economies of
scale.
Quorum
@[https://consensys.net/quorum/]
• Originally developed by JP Morgan as an extension to standard geth adding 
  support for private transactions and later on adquired by Consensys
  (that also develops Besu in parallel with the idea of support both of them).

  
• Private transactions are implemented to just a restrictect set of nodes.
  Such nodes will keep 2 states ("blockchains"), one for public transactions
  visible to all nodes, and a second one for private transactions.
  KEY POINT: Private granularity is done at enode scope.

  PRIVATE TX SIMPLIFIED SCHEMA:

  ┌ Node  ───┐     ┌ Node ────┐ • Each node trusted-admin will generate a couple of 
  │ @ClientA │     │ @ClientB │   priv/pub keys for the Tessera "side-car", keepingt
  │  ┌───────┤     ├───────┐  │   the private key "safe", and distributing the pub.
  │  │Tessera•·····•Tessera│  │   key to peers. Such pub.key will be used as recipient
  └──┴──────•┘     └•──────┴──┘   address when sending private transactions (to node
            ·       ·             or to group).
            └·┐   ┌·┘             
              ·   ·               NOTE: Not shown in diagram. Clients and 
            ┌─•───•─┬───────┐     regulators ussually have two parallel nodes.
            │Tessera│       │     One validator node that executes/validates
            ├───────┘       │     all incoming transactions in each new block,
            │ Regulator     │     and another node to attend client dApps.
            └ Node ─────────┘      The tessera "side-car" is normally installed
                                  on the dApps node used by dApp clients.
                                   In simple setups, validator can also be re-used
to serve dapps, query the blockchain, send new private/public TXs, but is less secure, 
since secrets are more exposed to the rest of the network.

 @[https://raw.githubusercontent.com/jpmorganchase/quorum-docs/master/images/QuorumTransactionProcessing.JPG]
   P┌====================================================================┐
   A│                           (9) TxAB-hash Payload?                   │
   R│                             ┌··················┐   (3,10)          │
   T│      (1) Private TX AB      ·(2)TXPayloadStore ·   En/De─crypt req.│
   Y│┌──────•····▷┌───────────────•───┬······▶┌──────▼─•···→┌───────────┐│
    ││ Dapp │     │ Quorum Node A     ├       │TX Mng A│    │ Enclave A ││
   A│└──────┘     │                   │◀······••────•──┘←···•───────────┘│
    │             │                   │    (6) ·    ┃ TX Resp.(4,11)     │
    │             │  Public  Private  │TX Hash ·    ┃                    │
    │             │  State    State   │        ·    ┃ (5)                │
    │             │  ┌────┐   ┌────┐  │◀·······┘    ┃ TXPayloadStore     │
    │    (8) Block│  ├────┤   ├────┤  │      (12)   ┃ private to A and B │
    │    with TxAB··▷└────┘   └────┘  │TX Payload   ┃                    │
    │ notarization│                   │             ┃                    │
    │         hash└───────────────────┘             ┃                    │
    │                 △                             ┃                    │
    │                 *                             ┃                    │
    └==== (7) Ethere. * ============================┃====================┘
          Standard TX *                             ┃
   P┌====    Protocol *=============================┃====================┐
   A│                 *       (9) TxAB-hash Payload?┃   (10) En/De-crypt │
   R│                 ▽          ┌·············┐    ┃  ┐request          │
   T│             ┌──────────────•────┐       ┌▼────▼──•···→┌───────────┐│
   Y│             │ Quorum Node B     │       │TX Mng B│    │ Enclave B ││
    │             │  Public  Private  │       └•───────┘←···•───────────┘│
   B│             │  State    State   │        ·     Tx Resp.(11)        │
    │             │  ┌────┐   ┌────┐  │        ·                         │
    │    (8) Block│  ├────┤   ├────┤  │        ·                         │
    │    with TxAB··▷└────┘   └────┘  │◀·······┘                         │
    │ notarization│                   │      (12)                        │
    │         hash└───────────────────┘TX Payload                        │
    │                 △                                                  │
    │                 *                                                  │
    └==== (7) Ethere. * =================================================┘
          Standard TX *
   P┌====    Protocol * =================================================┐
   A│                 *       (9) TxAB-hash Payload?                     │
   R│                 ▽          ┌·············┐                         │
   T│             ┌───────────────────┐       ┌▼───────┐    ┌───────────┐│
   Y│             │ Quorum Node C     │       │TX Mng C│    │ Enclave C ││
    │             │  Public  Private  │       └────────┘    └───────────┘│
   C│             │  State    State  Rº◀·······┘º                        │
    │             │  ┌────┐   ┌────┐  │Rº        (12)º                   │
    │    (8) Block│  ├────┤   ├────┤  │RºTX Not Foundº                   │
    │    with TxAB··▷└────┘   └────┘  │                                  │
    │ notarization│                   │                                  │
    │         hash└───────────────────┘                                  │
    └====================================================================┘
          △ △ △ △ △ △ △ △ △  ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
          * * * * * * * * *  · · · · · · · · · · · · · ·
          └───────────────┘  └─────────────────────────┘
            Ethereum standard       EEA PRIVATE TX
             p2p Protocol         EXTENSION PROTOCOL

• TESSERA (Private TX):
  • Developed in Java, used both by Quorum and Besu. 
    ('Orion' was used by the Go Quorum version, but later on its features
     were embedded into Tessera and the first one 'deprecated', 'Orion' 
     deprecated the (Haskell implementation) 'Constallation'.
  • used as a "side-car" of Besu/Quorum to manage private 
    communication of encrypted transactions to targeted nodes. (vs public 
    non-encrypted transactions -but still digitally signed- broadcasting 
    and propagating to all nodes). 
  • The enclave, a side-car of the Tessera side-car is use to manage secrets.
    Different enclave plugins exists:
    · local-filesystem keys.
    · Azure Key Vault key pairs.
    · HashiCorp Vault key pairs.
    · AWS Secrets Manager key pairs.

  - 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

Baseline Protocol Summary
@[https://docs.baseline-protocol.org/]
@[https://github.com/ethereum-oasis/baseline]
@[https://github.com/eea-oasis/baseline]

• See also Glossary: 
@[https://docs.baseline-protocol.org/baseline-basics/glossary]
• Baseline Protocol: set of methods that enable two or more state 
  machines to achieve and maintain data consistency, and workflow 
  continuity by using a network as a common frame of reference 
  through a Consensus Controlled State Machine (CCSM) like Ethereum 
  MainNet/.... RºWITHOUT MOVING ANY SENSITIVE DATA OUT OF OFº
RºTRADITIONAL SYSTEMS-OF-RECORDº.

• """ It is particularly promising as a way to reduce capital 
  expense and other overheads while increasing operational integrity 
  when automating business processes across multiple companies."""

• BaseLine Modules⅋Packages:
@[https://docs.baseline-protocol.org/baseline-protocol-code/packages]

  (@baseline-
  protocol)
  Package     Source Path   Description
  =========== ===========   =======================================
  /api        core/api      Core baseline API package providing 
                            unified access to the baseline JSON-RPC 
                            module and blockchain, registry and key 
                            management interfaces
  
  /baseline   core/baseline Core baseline  package provides unified 
                            access to internal integration 
                            middleware interfaces for systems of 
                            record
  
  
  /ccsm       core/ccsm     Core ccsm package provides interfaces 
                            for general interaction with an 
                            underlying mainnet
  
  /identitty  core/identity Core identity package provides interfaces 
                            for organization registry and decentralized 
                            identifiers (DIDs)
  
  /privacy    core/privacy  Core privacy package provides interfaces 
                            supporting Proversystems and and 
                            zero-knowledge cryptography
  
  
  /types      core/types    Core reusable type definitions
              
  /vaults     core/vaults   Core vault Provides management interfaces 
                            for digital authentication credentials such 
                            as keys and secrets
  
  


- https://docs.baseline-protocol.org/
- https://docs.baseline-protocol.org/baseline-protocol/packages/contracts

- Video 1 of 6: Baseline Protocol v0.1 Messaging
  https://www.youtube.com/watch?v=ZgaAcQvoD_8&feature=youtu.be

- Video 2 of 6 -- Baseline Protocol v0.1 API Registry Interface
  https://www.youtube.com/watch?v=lsZQwiE2glA&feature=youtu.be

- Video 3 of 6: Baseline Protocol v0.1 Privacy Introduction
  https://www.youtube.com/watch?v=l3BDBNMnR_Q&feature=youtu.be

- Video 4 of 6: Baseline Protocol v0.1 Privacy Deepdive
  https://www.youtube.com/watch?v=0vXoSb5bVks&feature=youtu.be

- Video 5 of 6: Baseline Protocol v0.1 Reference Implementation
  https://www.youtube.com/watch?v=2WXvTHR4_7Q&feature=youtu.be

- Video 6 of 6: Baseline Protocol v0.1 Reference Implementation Part 2
  https://www.youtube.com/watch?v=R0AEww6fKLk&feature=youtu.be

- https://github.com/ethereum-oasis/baseline/tree/master/core/privacy
- https://github.com/ethereum-oasis/baseline/tree/master/examples/bri-1


Who-is-Who -ºDaniel Norkinº: co-founder and CEO of Envision Blockchain. a full-service consultancy and Blockchain systems integrator. -ºStefan Schmidtºis the CTO, co-founder, and head of software architecture at Unibright. - Master of Computer Science - 20+years of experience in business modeling and software architecture. - always in search for the perfect harmony of architectural aesthetics and functional simplicity. -ºKyle Thomasº: Founder/CEO of Provide, cybersecurity and distributed systems polyglot and entrepreneur with experience shipping massively-scalable software to the public/private sectors. Salesforce + Baseline https://medium.com/baselineprotocol/dappsuite-extends-the-salesforce-platform-to-leverage-baseline-protocol-for-b2b-workflow-e466cf85c3f0
EEA-Besu
External Resources
• Chat     : @[https://chat.hyperledger.org/channel/besu]
• Releases : @[https://github.com/hyperledger/besu/releases]
• Core Devs: @[https://github.com/hyperledger/besu/graphs/contributors?from=2021-06-01&to=2022-02-01&type=c]
(Pegasys Pantheon was renamed to Besu after joining the Hyperledger Fundation)
Introduction
- 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... """

UUID: a4c55453-c75d-4faf-91aa-ae437ef80e97
ARCHITECTURE
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│                              JSON RPC                                                       │
└─────────────────────────────────────────────────────────────────────────────────────────────┘
╔═ CORE ("Mining") ═════╗ ╔ CHAIN PROCESSING ═══════╗ ╔ P2P ══════════════════════════════════╗
║╔═ SYNCHRONIZER ══════╗║ ║ PROTOCOL SPEC:          ║ ║╔ ETH SUB-PROTOCOL ═══════════════════╗║
║║ ● DOWNLOADER        ║║ ║ Update chain-of-blocks: ║ ║║┌ ETH PEER ─────────┐─┌ EXECUTORS ──┐║║
║║                     ║║ ║                         ║ ║║│                   │ │             │║║
║║ ● BLOCK PROPAGATION ║║ ║ ● BLOCK     ● TX        ║ ║║│ ● WIRE-CONNECTION │ │● SYNC WORKER│║║
║║   MANAGER           ║║ ║   HEADER      VALIDATOR ║ ║║│ ● REQUEST-MANAGER │ │● TX WORKER  │║║
║╚═════════════════════╝║ ║   VALIDATOR             ║ ║║│ ● PEER-REPUTATION │ │● SCHEDULED  │║║
║╔ TX POOL ════════════╗║ ║                         ║ ║║│ ● CHAIN-STATE     │ └─────────────┘║║
║║ ● PENDING  ● TX     ║║ ║ ● BLOCK     ● BLOCK     ║ ║║└───────────────────┘                ║║
║║   TXs        SENDER ║║ ║   IMPORTER    PROCESSOR ║ ║║ ● ETH MESSAGER                      ║║
║╚═════════════════════╝║ ╚═════════════════════════╝ ║╚═════════════════════════════════════╝║
║ ● MINER               ║                             ║┌─WIRE P2P PROTOCOL──────────────────┐ ║
╚═══════════════════════╝                             ║└────────────────────────────────────┘ ║
                                                      ║┌ DISCOVERY AGENT ───────────────────┐ ║
            ╔═ STATE  ══════════════════╗             ║└──▲─────────────────────────────────┘ ║
            ║┌ WORLD───┐ ┌ BLOCKCHAIN ┐ ║             ╚═══│═══════════════════════════════════╝
            ║│ STATE   │ │            │ ║       • DEVp2 Peer Discovery
            ║│ ARCHIVE │ │            │ ║         . UDP-based system to discover other nodes
            ║└─────────┘ └────────────┘ ║         . Based on a ºwell-known set of boot nodesº.
            ║┌CONSENSUS┐ ┌ SYNC STATE ┐ ║           . Recursively looks up new peers (neighbors)
            ║└─────────┘ └────────────┘ ║             from known peers.
            ╚═══════════════════════════╝       • DISCOVERY (of (neighbors IP) PACKET EXCHANGE 
                                                  Node_A → Node_B: Ping        
                                                  Node_A ← Node_B: Pong
                                                  Node_A → Node_B: Find Neighbors 
                                                  Node_A ← Node_B: known-neighbors list

  besu  /                              $º$ bin\besu --config=my.cfg \        º
     ├─ bin/ (install)                 $º  --data-path=/var/lib/besu/node1 \ º
     ├─ lib/ (install)                 $º  --genesis=my.genesis \            º
     ├─ key  (run─time) eNode Priv.key $º  --max-peers=5 \                   º
     │  (--data-path)                  $º  --rpc-enabled                     º
     └─ ddbb (run─time) RocksDB data   ( LOGS go to STDOUT )
        (--data-path)

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 BesuController
 @[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
    - Besu 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"
Governance
Onchain Permissioning
@[https://besu.hyperledger.org/en/stable/Concepts/Permissioning/Onchain-Permissioning/]
Updated on 2020-03-20

- Permissioning smart contracts used to store and administer the
  node, account, and admin whitelists. (vs whitelists in config files with the
  potential to have errors or not bein in sync).

- Permissioning Management Dapp is located in repository
  PegaSysEng/permissioning-smart-contracts.

- Custom smart contracts and dapps can be implemented to work with
  onchain permissioning.

- Existing Permissioning contracts:
  -ºIngress contractsº: proxy contracts defined in the genesis file to defer the
   ºfor nodes andº      permissioning logic to the Node Rules and Account Rules contracts.
   ºaccountsº           The Ingress contracts deploy to static addresses.

  -ºNode Rulesº       : stores node whitelist and node whitelist operations
                       (for example, add and remove).

  -ºAccount Rulesº    : stores the accounts whitelist and account
                        whitelist operations (for example, add and remove).

  -ºAdminº            : stores the list of admin accounts and admin list
                        operations (for example, add and remove). There is one
                        list of admin accounts for node and accounts.

- Permissioning management Dapp:
  - provides view and maintain access to the whitelists.

- Whitelists implemented:
  - Accounts: can submit transactions to the network.
  - Nodes   : can join the network.
            ☞ All bootnodes must be on the nodes whitelist.
  - Admins  : accounts able to update the accounts and nodes whitelists

- Account permissioning Rºis incompatibleº with random key
  signing for privacy marker transactions.
  - A signing key must be specified using the
    [--privacy-marker-transaction-signing-key-file] cli flag,
    and also included in the accounts whitelist.

@[https://besu.hyperledger.org/en/stable/HowTo/Limit-Access/Local-Permissioning/]
Web3J(ava)
@[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 Besu.
ºbenesjanº: ... There is one issue with creating common Geth and Besu module.
                Geth's version of minerStart accepts parameter threadCount and
                Besu's version does not. So unifying those two might be confusing.
ºconor10 º: ... let’s leave the duplication in for now ...
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.
                     (RLP encoding is how value is stored in current Ethereum implementation
                      key-value store -"leaf" of the Patricia-Merkle Tries)

 ºbesu  operator generate-blockchain-configº generates node keypairs+genesis file
                                             (with RLP encoded IBFT 2.0 extra data).

ºCLI Optionsº
@[https://besu.hyperledger.org/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 "all"  # 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=$NETWORK
                                           # 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)

Oº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!!!º

ºGossip protocolº
  --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.


OºAccount Permissioningº (onchain permissioning is preferred)
  --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 Tessera node.
  --privacy-url=privacyUrl                            # URL on which Tessera node is running.

Oº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 "all"        # 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

Oº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.


Oº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.

OºLoggingº
  --logging=OFF|FATAL|ERROR|WARN|INFO*|DEBUG|TRACE|ALL

Oº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.
Besus GraphQL Schema 
@[https://github.com/hyperledger/besu/blob/master/ethereum/api/src/main/resources/schema.graphqls]
# Bytes32 is a 32 byte binary string, represented as 0x-prefixed hexadecimal.
scalar Bytes32
# Address is a 20 byte Ethereum address, represented as 0x-prefixed hexadecimal.
scalar Address
# Bytes is an arbitrary length binary string, represented as 0x-prefixed hexadecimal.
# An empty byte string is represented as '0x'. Byte strings must have
# an even number of hexadecimal nybbles.
scalar Bytes
# BigInt is a large integer. Input is accepted as either a JSON number or as a string.
# Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all
# 0x-prefixed hexadecimal.
scalar BigInt
# Long is a 64 bit unsigned integer.
scalar Long

schema {
    query: Query
    mutation: Mutation
}

# Account is an Ethereum account at a particular block.
type Account {
    # Address is the address owning the account.
    address: Address!
    # Balance is the balance of the account, in wei.
    balance: BigInt!
    # TransactionCount is the number of transactions sent from this account,
    # or in the case of a contract, the number of contracts created. Otherwise
    # known as the nonce.
    transactionCount: Long!
    # Code contains the smart contract code for this account, if the account
    # is a (non-self-destructed) contract.
    code: Bytes!
    # Storage provides access to the storage of a contract account, indexed
    # by its 32 byte slot identifier.
    storage(slot: Bytes32!): Bytes32!
}

# Log is an Ethereum event log.
type Log {
    # Index is the index of this log in the block.
    index: Int!
    # Account is the account which generated this log - this will always
    # be a contract account.
    account(block: Long): Account!
    # Topics is a list of 0-4 indexed topics for the log.
    topics: [Bytes32!]!
    # Data is unindexed data for this log.
    data: Bytes!
    # Transaction is the transaction that generated this log entry.
    transaction: Transaction!
}

# Transaction is an Ethereum transaction.
type Transaction {
    # Hash is the hash of this transaction.
    hash: Bytes32!
    # Nonce is the nonce of the account this transaction was generated with.
    nonce: Long!
    # Index is the index of this transaction in the parent block. This will
    # be null if the transaction has not yet been mined.
    index: Int
    # From is the account that sent this transaction - this will always be
    # an externally owned account.
    from(block: Long): Account!
    # To is the account the transaction was sent to. This is null for
    # contract-creating transactions.
    to(block: Long): Account
    # Value is the value, in wei, sent along with this transaction.
    value: BigInt!
    # GasPrice is the price offered to miners for gas, in wei per unit.
    gasPrice: BigInt!
    # Gas is the maximum amount of gas this transaction can consume.
    gas: Long!
    # InputData is the data supplied to the target of the transaction.
    inputData: Bytes!
    # Block is the block this transaction was mined in. This will be null if
    # the transaction has not yet been mined.
    block: Block

    # Status is the return status of the transaction. This will be 1 if the
    # transaction succeeded, or 0 if it failed (due to a revert, or due to
    # running out of gas). If the transaction has not yet been mined, this
    # field will be null.
    status: Long
    # GasUsed is the amount of gas that was used processing this transaction.
    # If the transaction has not yet been mined, this field will be null.
    gasUsed: Long
    # CumulativeGasUsed is the total gas used in the block up to and including
    # this transaction. If the transaction has not yet been mined, this field
    # will be null.
    cumulativeGasUsed: Long
    # CreatedContract is the account that was created by a contract creation
    # transaction. If the transaction was not a contract creation transaction,
    # or it has not yet been mined, this field will be null.
    createdContract(block: Long): Account
    # Logs is a list of log entries emitted by this transaction. If the
    # transaction has not yet been mined, this field will be null.
    logs: [Log!]
}

# BlockFilterCriteria encapsulates log filter criteria for a filter applied
# to a single block.
input BlockFilterCriteria {
    # Addresses is list of addresses that are of interest. If this list is
    # empty, results will not be filtered by address.
    addresses: [Address!]
    # Topics list restricts matches to particular event topics. Each event has a list
  # of topics. Topics matches a prefix of that list. An empty element array matches any
  # topic. Non-empty elements represent an alternative that matches any of the
  # contained topics.
  #
  # Examples:
  #  - [] or nil          matches any topic list
  #  - [[A]]              matches topic A in first position
  #  - [[], [B]]          matches any topic in first position, B in second position
  #  - [[A], [B]]         matches topic A in first position, B in second position
  #  - [[A, B]], [C, D]]  matches topic (A OR B) in first position, (C OR D) in second position
    topics: [[Bytes32!]!]
}

# Block is an Ethereum block.
type Block {
    # Number is the number of this block, starting at 0 for the genesis block.
    number: Long!
    # Hash is the block hash of this block.
    hash: Bytes32!
    # Parent is the parent block of this block.
    parent: Block
    # Nonce is the block nonce, an 8 byte sequence determined by the miner.
    nonce: Bytes!
    # TransactionsRoot is the keccak256 hash of the root of the trie of transactions in this block.
    transactionsRoot: Bytes32!
    # TransactionCount is the number of transactions in this block. if
    # transactions are not available for this block, this field will be null.
    transactionCount: Int
    # StateRoot is the keccak256 hash of the state trie after this block was processed.
    stateRoot: Bytes32!
    # ReceiptsRoot is the keccak256 hash of the trie of transaction receipts in this block.
    receiptsRoot: Bytes32!
    # Miner is the account that mined this block.
    miner(block: Long): Account!
    # ExtraData is an arbitrary data field supplied by the miner.
    extraData: Bytes!
    # GasLimit is the maximum amount of gas that was available to transactions in this block.
    gasLimit: Long!
    # GasUsed is the amount of gas that was used executing transactions in this block.
    gasUsed: Long!
    # Timestamp is the unix timestamp at which this block was mined.
    timestamp: BigInt!
    # LogsBloom is a bloom filter that can be used to check if a block may
    # contain log entries matching a filter.
    logsBloom: Bytes!
    # MixHash is the hash that was used as an input to the PoW process.
    mixHash: Bytes32!
    # Difficulty is a measure of the difficulty of mining this block.
    difficulty: BigInt!
    # TotalDifficulty is the sum of all difficulty values up to and including
    # this block.
    totalDifficulty: BigInt!
    # OmmerCount is the number of ommers (AKA uncles) associated with this
    # block. If ommers are unavailable, this field will be null.
    ommerCount: Int
    # Ommers is a list of ommer (AKA uncle) blocks associated with this block.
    # If ommers are unavailable, this field will be null. Depending on your
    # node, the transactions, transactionAt, transactionCount, ommers,
    # ommerCount and ommerAt fields may not be available on any ommer blocks.
    ommers: [Block]
    # OmmerAt returns the ommer (AKA uncle) at the specified index. If ommers
    # are unavailable, or the index is out of bounds, this field will be null.
    ommerAt(index: Int!): Block
    # OmmerHash is the keccak256 hash of all the ommers (AKA uncles)
    # associated with this block.
    ommerHash: Bytes32!
    # Transactions is a list of transactions associated with this block. If
    # transactions are unavailable for this block, this field will be null.
    transactions: [Transaction!]
    # TransactionAt returns the transaction at the specified index. If
    # transactions are unavailable for this block, or if the index is out of
    # bounds, this field will be null.
    transactionAt(index: Int!): Transaction
    # Logs returns a filtered set of logs from this block.
    logs(filter: BlockFilterCriteria!): [Log!]!
    # Account fetches an Ethereum account at the current block's state.
    account(address: Address!): Account!
    # Call executes a local call operation at the current block's state.
    call(data: CallData!): CallResult
    # EstimateGas estimates the amount of gas that will be required for
    # successful execution of a transaction at the current block's state.
    estimateGas(data: CallData!): Long!
}

# CallData represents the data associated with a local contract call.
# All fields are optional.
input CallData {
    # From is the address making the call.
    from: Address
    # To is the address the call is sent to.
    to: Address
    # Gas is the amount of gas sent with the call.
    gas: Long
    # GasPrice is the price, in wei, offered for each unit of gas.
    gasPrice: BigInt
    # Value is the value, in wei, sent along with the call.
    value: BigInt
    # Data is the data sent to the callee.
    data: Bytes
}

# CallResult is the result of a local call operation.
type CallResult {
    # Data is the return data of the called contract.
    data: Bytes!
    # GasUsed is the amount of gas used by the call, after any refunds.
    gasUsed: Long!
    # Status is the result of the call - 1 for success or 0 for failure.
    status: Long!
}

# FilterCriteria encapsulates log filter criteria for searching log entries.
input FilterCriteria {
    # FromBlock is the block at which to start searching, inclusive. Defaults
    # to the latest block if not supplied.
    fromBlock: Long
    # ToBlock is the block at which to stop searching, inclusive. Defaults
    # to the latest block if not supplied.
    toBlock: Long
    # Addresses is a list of addresses that are of interest. If this list is
    # empty, results will not be filtered by address.
    addresses: [Address!]
    # Topics list restricts matches to particular event topics. Each event has a list
  # of topics. Topics matches a prefix of that list. An empty element array matches any
  # topic. Non-empty elements represent an alternative that matches any of the
  # contained topics.
  #
  # Examples:
  #  - [] or nil          matches any topic list
  #  - [[A]]              matches topic A in first position
  #  - [[], [B]]          matches any topic in first position, B in second position
  #  - [[A], [B]]         matches topic A in first position, B in second position
  #  - [[A, B]], [C, D]]  matches topic (A OR B) in first position, (C OR D) in second position
    topics: [[Bytes32!]!]
}

# SyncState contains the current synchronisation state of the client.
type SyncState{
    # StartingBlock is the block number at which synchronisation started.
    startingBlock: Long!
    # CurrentBlock is the point at which synchronisation has presently reached.
    currentBlock: Long!
    # HighestBlock is the latest known block number.
    highestBlock: Long!
    # PulledStates is the number of state entries fetched so far, or null
    # if this is not known or not relevant.
    pulledStates: Long
    # KnownStates is the number of states the node knows of so far, or null
    # if this is not known or not relevant.
    knownStates: Long
}

# Pending represents the current pending state.
type Pending {
  # TransactionCount is the number of transactions in the pending state.
  transactionCount: Int!
  # Transactions is a list of transactions in the current pending state.
  transactions: [Transaction!]
  # Account fetches an Ethereum account for the pending state.
  account(address: Address!): Account!
  # Call executes a local call operation for the pending state.
  call(data: CallData!): CallResult
  # EstimateGas estimates the amount of gas that will be required for
  # successful execution of a transaction for the pending state.
  estimateGas(data: CallData!): Long!
}

type Query {
    # Account fetches an Ethereum account at the specified block number.
    # If blockNumber is not provided, it defaults to the most recent block.
    account(address: Address!, blockNumber: Long): Account!
    # Block fetches an Ethereum block by number or by hash. If neither is
    # supplied, the most recent known block is returned.
    block(number: Long, hash: Bytes32): Block!
    # Blocks returns all the blocks between two numbers, inclusive. If
    # to is not supplied, it defaults to the most recent known block.
    blocks(from: Long!, to: Long): [Block!]!
    # Pending returns the current pending state.
    pending: Pending!
    # Transaction returns a transaction specified by its hash.
    transaction(hash: Bytes32!): Transaction
    # Logs returns log entries matching the provided filter.
    logs(filter: FilterCriteria!): [Log!]!
    # GasPrice returns the node's estimate of a gas price sufficient to
    # ensure a transaction is mined in a timely fashion.
    gasPrice: BigInt!
    # ProtocolVersion returns the current wire protocol version number.
    protocolVersion: Int!
    # Syncing returns information on the current synchronisation state.
    syncing: SyncState
}

type Mutation {
    # SendRawTransaction sends an RLP-encoded transaction to the network.
    sendRawTransaction(data: Bytes!): Bytes32!
}
What's New
BºQuorum 21 (2021-03-09):º
  (Enhanced Ethereum Mainnet Compatibility, lower infrastructure costs and ease of use)
  REF:
  @[https://consensys.net/blog/quorum/consensys-quorum-21-1-0-features-enhanced-ethereum-mainnet-compatibility/]
  - Enhanced compatibility between Besu and GoQuorum.

  - Besu mainnet Improvements for Network Upgrades, Database and Storage:

    - Compatibility with BºMainNet Berlin Network Upgradeº
      (next planned MainNet hard fork)
      -  addition of subroutines to the EVM,
      -  introduction of º"transaction envelopes"º making it simpler for Ethereum
         to support several different kinds of transactions
      -  changes in gas costs to increase the security of the network.
       RºWARNº: Use 21.1.2 or higher. Rº21.1.0 contains an outdated versionº of Berlin upgrade.
      -  Mainnet Launcher "wizard"
      -BºBonsai Triesº(Early Access): new database formatBºreducing storage requirementsº
         and improves performance for access to recent state.

         BºNON-BONSAI TRIES                 BONSAI TRIESº
           - multi-trie key/val store     - single trie.
                                          - one set of indexed leafs
                                          - N diffs that can be used
                                            to move the trie forward
                                            or backwards.
                                          --------------------------
                                          - reduce chain head count and
                                            state read and write amplification
                                          Bºfrom 10x-20x levels to 1x-2x for º
                                          Bºnon-committed access.º

                                          - Note: only full sync currently supported.

  -  New monitoring API detects nodes non initiating or receiving TX
     for a period-of-time andBºstops+hibernates them to reduce infra. cost.º

  -BºMulti-Tenancy in GoQuorum/Tessera nodesº.

Bº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]
  └ Bº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

  └ future work: Besu will 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.

  └ privacy use in a Bºmulti-tenacyº environment;
  @[https://pegasys.tech/increase-adoption-and-cut-costs-with-multi-tenancy-on-hyperledger-besu/]
    (many clients re-using the same Ethereum client node
    whilst maintaining the privacy and confidentiality )
    with support for authenticated API access and allowing hosts who
    standup the infrastructure custom control on who to grant access to,
    at various levels of granularity depending on the
    users need, Bºcoupled with Tessera private TX managerº.
    - By using BºJWT tokensº, a user identity is tied to a privacy
      identity, validating every API call to ensure the user
      is part of the privacy group before any data is revealed.
    (WiP for EthSigner and PegaSys Orchestrate multi-tenancy)

  └ Early access to flexible privacy groups allowing addition and
    removal of privacy group members;

  └ New tracing APIs
  └ Event Streaming Improvements
  └ Advanced Key Management
  └ Flexible privacy calls
  └ New privacy APIs
  └ End to end encryption with TLS links between PegaSys suite products


Bº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.
      @[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.
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://besu.hyperledger.org/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://eth.wiki/en/fundamentals/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://besu.hyperledger.org/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://besu.hyperledger.org/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 besu-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, ...
backup, disaster recovery
Monitoring Performance
(Prometh.+Grafana)
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.


REF: @[https://lists.hyperledger.org/g/besu/message/34]
Re: How to Monitor Performance for Multiple Nodes?
...  you can use the promethus metrics server.
(--metrics-enabled and --metrics-categories=JVM,PROCESS).
In addition to enabling it you would need a prometheus server
to poll the metrics and something like grafana to make it presentable.

Here is a mechanical dump of all of the Prometheus metrics that we currently can export:

@[https://gist.github.com/shemnon/bff32ff78ff42cb2d51f76effba0d311]
Most relevant are the jvm_ and process_ metrics, which are standard prometheus names.

Block gas limit of the current chain head block
Gas used by the current chain head block
Number of ommers in the current chain head block
Timestamp from the current chain head
Number of transactions in the current chain head block
Total difficulty of the chainhead
Current number of threads executing tasks
Total number of tasks executed
Current number of threads in the thread pool
Current number of tasks awaiting execution
Total number of tasks rejected by this executor
Total number of tasks executed
Current number of threads executing tasks
Total number of tasks executed
Current number of threads in the thread pool
Current number of tasks awaiting execution
Total number of tasks rejected by this executor
Total number of tasks executed
Current number of threads executing tasks
Total number of tasks executed
Current number of threads in the thread pool
Current number of tasks awaiting execution
Total number of tasks rejected by this executor
Total number of tasks executed
Current number of threads executing tasks
Total number of tasks executed
Total number of tasks rejected by this working queue.
Current number of threads in the thread pool
Current number of tasks awaiting execution
Total number of tasks rejected by this executor
Total number of tasks executed
Current number of threads executing tasks
Total number of tasks executed
Current number of threads in the thread pool
Current number of tasks awaiting execution
Total number of tasks rejected by this executor
Total number of tasks executed
Current number of inflight discovery interactions
Total number of discovery interactions initiated
Total number of interaction retries performed
Total number of P2P discovery messages received
Total number of P2P discovery messages sent
The number of pending tasks in the Netty boss event loop
The number of pending tasks in the Netty workers event loop
Count of each P2P message received inbound.
Count of each P2P message sent outbound.
The number of pending tasks in the Vertx event loop
Total number of tasks completed by the Vertx worker pool
Total number of tasks rejected by the Vertx worker pool
Total number of tasks submitted to the Vertx worker pool
Total number of peers connected
Total number of peers disconnected
Number of peer requests currently pending because peers are busy
Latency for commits to RocksDB.
Latency for read from RocksDB.
Latency of remove requests from RocksDB.
Estimated database size in bytes
Estimated memory used for RocksDB index and filter blocks in bytes
Number of RocksDB transactions rolled back.
Latency for write to RocksDB.
Time taken to process a JSON-RPC request
Total number of subscriptions
Total number of unsubscriptions
Number of entries process by each chain download pipeline stage
Number of times the chain download pipeline has been restarted
Whether or not the local node has caught up to the best known peer
Internal processing tasks
Count of transactions added to the transaction pool
Total number of duplicate transactions received
Total number of transactions messages skipped by the processor.
Count of transactions removed from the transaction pool
The estimated highest block available
The current height of the canonical chain
The current number of peers connected
The maximum number of peers this node allows to connect
Bytes capacity of a given JVM buffer pool.
Used buffers of a given JVM buffer pool.
Used bytes of a given JVM buffer pool.
The number of classes that are currently loaded in the JVM
The total number of classes that have been loaded since the JVM has started execution
The total number of classes that have been unloaded since the JVM has started execution
Time spent in a given JVM garbage collector in seconds.
Committed (bytes) of a given JVM memory area.
Initial bytes of a given JVM memory area.
Max (bytes) of a given JVM memory area.
Used bytes of a given JVM memory area.
Committed bytes of a given JVM memory pool.
Initial bytes of a given JVM memory pool.
Max bytes of a given JVM memory pool.
Used bytes of a given JVM memory pool.
Current thread count of a JVM
Daemon thread count of a JVM
Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers
Cycles of JVM-threads that are in deadlock waiting to acquire object monitors
Peak thread count of a JVM
Started thread count of a JVM
Current count of threads by state
Total user and system CPU time spent in seconds.
Maximum number of open file descriptors.
Number of open file descriptors.
Start time of the process since unix epoch in seconds.
RocksDB statistics (cache,  compression, ...)

  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.
Outdated link: 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.
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 Governance
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.

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/]
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)}
                           )
                        }
                      )
Tech.Radar
EthrDIDs"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.º
Zero Know. Range Pro. (ZKRP)
@[https://github.com/ing-bank/zkrp]
• ING Bank:
  ...Launched in 2017, zero-knowledge range proof (ZKRP) enabled numerical
  data to be validated within a number range. For example, a mortgage
  applicant could prove that their salary sits within a certain range
  without revealing the exact figure. A year later, ING took the
  solution a step further and introduced ZKSM, which goes beyond
  numerical data to include other types of information, like locations
  and names. This made the new code, ZKSM, more powerful. For instance,
  banks could validate that a new client lives in a country that
  belongs to the European Union, without revealing the country. Simply
  put, this allows for information to be shared without revealing
  contextual details.
  
  Following a trend now widely adopted in the industry Bulletproofs
  code is open-source, which means that other interested parties in the
  development community are able to use, access and even contribute to
  the solution.
Augur Prediction Markets (Research project)
@[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
- ...
Status: Wallet and IM
@[https://status.im/]
@[https://github.com/status-im/status-react]
- currently (20??-??) 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}
Homomorphic Hashing
@[http://blog.notdot.net/2012/08/Damn-Cool-Algorithms-Homomorphic-Hashing]
SuperSonic: zSNARK trustless setup
• Ben Fisch, Benedikt, and Alan Szepeniec also recently introduced
  SuperSonic, the first fully practical zero-knowledge SNARK that
  doesn't require a trusted setup.

• ... guest speaker Brecht Devos of Loopring for a presentation and
  Q+A about scaling with ZKPs and Loopring.
Bulletproofs
• Bulletproofs are short non-interactive zero-knowledge proofs that 
  require no trusted setup. A bulletproof can be used to convince a 
  verifier that an encrypted plaintext is well formed. For example, 
  prove that an encrypted number is in a given range, without revealing 
  anything else about the number. Compared to SNARKs, Bulletproofs 
  require no trusted setup. However, verifying a bulletproof is more 
  time consuming than verifying a SNARK proof. 
• used to secure cryptocurrencies like Monero, Mimblewimble
  and others and is used in enterprise blockchains like JP
  Morgan's quorum.
verifiable delay functions
- core building block for proof stake block chains and
  secure lotteries.
The Matter (500 TX/s)
- @[https://thematter.io/]
- (Etheeum 2019 Grant)
- Productionising ‘Plasma Ignis’ code, a SNARK-driven “roll up” that can
  support up to 500 transactions per second.
EIP 648
@[https://github.com/ethereum/EIPs/issues/648] (V. Buterin)
• Introduce new type of transaction (following same general format as #232):
  [2, network_id, startgas, to, data, ranges]
  Where ranges is an RLP list, where each value in the list is an
  address prefix, representing the range of all addresses with that
  prefix.
• Rationale:
  transactions in the EVM to be processed in parallel much more easily,
  by specifying statically what addresses they can access; it also
  appropriately incentivizes making transactions that are easy to
  parallelize. It does this in a maximally backwards-compatible and
  non-intrusive way where old-style transactions can continue to work.
Deth (Ganache alt)
@[https://github.com/ethereum-ts/deth]
- Ganache alternative:
  -  RPC support
  -  state snapshots (evm_snapshot), time manipulation (evm_increaseTime),
     mining control (evm_mine)
  -  print out decoded logs and calldata for all transactions
     (even reverted ones!)
  -  display revert reasons
  -  built-in blockchain explorer
  -  ignore nonce errors(perfect while working with Metamask fox_face)
  -Bºmuch faster (60%) than Ganacheº
Avalon
@[https://www.infoq.com/news/2019/10/Hyperledger-Avalon-Blockchain/]
Improving Blockchain Performance Off-Chain, Hyperledger Announces Avalon
• Hyperledger Avalon, aims to move blockchain processing off the main
  chain to dedicated computing resources, e.g. Intel SGX TEE.
  using "computational trust".
• Broadly supported blockchain project and  organizations like Intel,
  iExec Blockchain Tech, Alibaba Cloud, Baidu, Chainlink, ConsenSys,
  IBM, Microsoft and Oracle.
• Project previously executed underneath the Trusted Compute Framework(TCF)
  name.
• collaboration across the Hyperledger project, Enterprise Ethereum
  Alliance and the cloud provider ecosystem.

Who is Who:
Eugene Yarmosh: systems architect at Intel, and has over 20 years
of experience designing and building distributed and decentralized
solutions spanning from embedded firmware to large-scale cloud
solutions. During the last several years, Eugene has focused on
scalability and privacy solutions for public and private blockchains,
specifically utilizing HW based trusted execution environments (TEE)
for off-chain workload execution. Eugene is an editor of the EEA
Off-chain Trusted Compute Specification and is a lead architect for
Hyperledger Avalon, a ledger-independent reference implementation of
the Trusted Compute specification. He also holds several patents.

AlphaWallet, Portis/ShapeShift
AlphaWallet TokenScripts ("Smart Tokens")
• AlphaWallet is a production-ready white-label wallet that is easy to
  customize. TokenScript is similar to web frameworks used by web apps,
  combining the attributes of a blockchain-based token and the perks of
  a web app, allowing users to interact directly with
  blockchain-powered applications and services.

• It tries to solve the Trilemma "Security,Decentralization,Scalability".

• It consists of protocols chaining Dapss with Side Chains and "Main" Chains
  converting "value" into "tokens" than can be used in the AlphaWallet 
  mobile platform.  Its core strategy is to "move" as much as possible 
  off-chain while keeping it only validation logic on-chain.

• A TokenScript file is made of:
  - JavaScript to make Token work in the user's wallet or across multiple apps; and
  - XML data to extract status and value of the token.

  In short, it's like a Bºsecure front-end for tokensº.

• Benefits
  - Run your tokens from users wallets as native, modular ‘Mini-DApps'
  - Extend token structure and realise rich functions with a single file
  - Portable across DApps
  - Sync updates at any time
  - Blockchain agnostic
  - Secure Enclave
  - DvP Security
  - Context based programming: User-experience
  - Attestation

- Who-is-Who:
  Wei Wu Zhang: head of development for AlphaWallet

• Portis is a self-custody blockchain wallet and Web3 access provider.
  It is powered by ShapeShift and provides access to multiple networks
  including Ethereum, Bitcoin, SKALE, xDai, and many others. It
  supports easy onboarding and user engagement and is trusted by a
  growing number of the most popular decentralized applications. Tom
  Teman, a co-founder at Portis, will be the presenter
Non Classified / TODO
Gemalto HSM
@[https://safenet.gemalto.com/data-encryption/hardware-security-modules-hsms/protectserver-security-module/]
- Supports SECP256K1 , required by Ethereum
Mnemonic to Seed
@[https://ethereum.stackexchange.com/questions/25484/could-address-reuse-leak-your-mnemonic-seed/25705#2570://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#from-mnemonic-to-seed]

 (mnemonic, passphrase) → (input to) → │PBKDF2│ ──────────────→  derived key ("seed")
  ^            ^^                         ^                      512 bits (64 bytes)
  └ UTF-8 NFKD ┘|              - Iter.count : 2048                ^
                |              - HASH       : HMAC-SHA512        Can be used to generate
                |                                                deterministic keys (wallets)
                |                                                (BIP-0032)
       every "random" passphrase
       generates a valid seed but
       only the correct one will
       make the desired wallet available
Azure offline signing
@[https://tomislav.tech/2018-02-05-ethereum-keyvault-signing-transactions/]
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]
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
Buidler
@[https://buidler.dev/]
@[https://www.npmjs.com/package/@nomiclabs/buidler-ethers]

""" Turn a mess of tricky Solidity tools into a smooth workflow """
...

- 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]
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.
Libraries
@[https://solidity.readthedocs.io/en/develop/contracts.html#libraries]


- https://github.com/ethereum/solidity/issues/3985
  Should we clarify when library code is linked vs embedded?
Mine Only on Pending TXs
    @[https://ethereum.stackexchange.com/questions/3151/how-to-make-miner-to-mine-only-when-there-are-pending-transactions]
    - How to make miner to mine only when there are Pending Transactions?
      As of now the geth miner running on my system mines even empty blocks.

- How to do that same in Besu, Parity, ...? 
Deconstructing a Sol. Contract
@[https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-i-introduction-832efd2d7737/]
Ether Vault (Anti-theft)
https://www.blunderingcode.com/ether-vaults/
- The basic idea is to have a hot wallet account, plus a contract which
  holds the bulk of your ether, and stores a vault key and recovery
  key. Most of the money is vaulted and inaccessible. To unvault some
  of it, use the vault key. After a delay the vault key can send the
  money to your hotwallet.
Ephemeral Testnet YOLO
In preparation for the next network upgrade, Berlin, an ephemeral
testnet called YOLO was launched with two new EIPs enabled: EIP-2315,
which adds subroutines to the EVM, and EIP-2537, which introduces a
new precompile for the BLS12-381 curve.
OrbitDB
@[https://orbitdb.org/]
- OrbitDB is a serverless, distributed, peer-to-peer database. OrbitDB
  uses IPFS as its data storage and IPFS Pubsub to automatically sync
  databases with peers. It’s an eventually consistent database that
  uses CRDTs for conflict-free database merges making OrbitDB an
  excellent choice for decentralized apps (dApps), blockchain
  applications and offline-first web applications.

- "Alternatives":
  - DOLT: Distributed SQL ddbb on top of Git.
EIP vs ERC
- ERC are a subset of EIPs for application-level standards and
  conventions, including contract standards such as token standards
  (ERC-20), name registries (ERC-137), URI schemes (ERC-681),
  library/package formats (EIP190), and wallet formats (EIP-85).
Legions
@[https://diligence.consensys.net/blog/2020/06/legions-a-tool-for-seekers/]

" Tool to poke around Geth Nodes in the terminal."
  -  Poke around a public Ethereum node JSON RPC endpoints?
  -  See if an Ethereum node is mining or not?
  -BºRead the storage of a smart contract? And maybe see how the º    [persistence.contract_state]
   Bºstorage changed between different block numbers? º
  -BºGet the bytecode of a smart contract without going to etherscan? º
  -  List all ENS domains names owned by an address and their expiry dates?



So I began building a tool for that specific engagement. As the
engagement went on, certain other tasks kept cropping up, such as
simple Wei to Eth conversion, or more challenging tasks like reading
the storage of a smart contract.
Is there anything better than a cool command-line interface?

Legions is now open-source and also available on Pypi Package manager.

Simply install the package for python 3.6+ and everything else should
be easy to find with the interactive interface:

$º$ pip install legions º
ethereum-etl
RºWARN:º See limitation in Github Project page.
Export blocks and transactions (Schema, Reference):
$º$ python export_blocks_and_transactions.py \                   º
$º  --start-block 0 --end-block 500000 \                         º
$º  --provider-uri https://mainnet.infura.io \                   º
$º  --blocks-output blocks.csv --transactions-output \           º
$º  transactions.csv                                             º

Export ERC20 and ERC721 transfers (Schema, Reference):
$º$ python export_token_transfers.py \                           º
$º  --start-block 0 --end-block 500000 \                         º
$º  --provider-uri file://$HOME/Library/Ethereum/geth.ipc \      º
$º  --output token_transfers.csv                                 º

Export receipts and logs (Schema, Reference):
$º$ python export_receipts_and_logs.py --transaction-hashes \    º
$º  transaction_hashes.txt \                                     º
$º  --provider-uri https://mainnet.infura.io --receipts-output \ º
$º  receipts.csv --logs-output logs.csv                          º

Export ERC20 and ERC721 token details (Schema, Reference):
$º$ python export_tokens.py \                                    º
$º  --token-addresses token_addresses.csv \                      º
$º  --provider-uri https://mainnet.infura.io --output tokens.csv º

Export traces (Schema, Reference):
$º$ python export_traces.py --start-block 0 --end-block 500000 \ º
$º  --provider-uri file://$HOME/Library/Ethereum/parity.ipc \    º
$º  --output traces.csv                                          º
NuCypher
- Cryptographic Infrastructure for Privacy-Preserving Applications

- Manage secrets such as IAM tokens, database and SSH credentials,
  X.509 certificates, and signing/encryption keys across dynamic
  environments.
Algorithmic stablecoins
REF: @[https://frax.finance/whitepaper/]
     @[https://github.com/FraxFinance/frax-truffle/blob/master/test/Frax-Tests.js]
- Although there are many ways to categorise stablecoins, two distinct
  design concepts have stood out over time:
  - collateralized stablecoins:
    - Main categories:
      - crypto-collateralized (MakerDAO’s Dai)
      - fiat-collateralized tokens (Tether, BUSD, USDC)
    (both subgroups having had significant adoption).
  - algorithmic stablecoins :
    - attempt to change the circulating supply of the token
      so that changes in demand for the stablecoin minimally
      affect its price.
    - Bºnot collateralized or redeemable forº
      Bºan underlying asset.º
    - no significant traction (high profile attempts done):
      " ... We contend that a prevailing reason
        for the lack of traction of algorithmic
        stablecoins was not their economic
        infeasibility, but their flawed designs
        and execution..."
        https://frax.finance/whitepaper/
EthTrust
external REF

Enterprise Ethereum Alliance Launches EthTrust Security Initiative to
Advance Confidence in Ethereum as a Global Settlement Layer for
Transactions of All Types

.. The Working Group’s mission will be to continue the advances begun
 by the Ethereum Trust Alliance (ETA), now part of the EEA, on the
 EthTrust project, that will :
Bºset standards for secure, smart contract transactions that are º
Bºconducted within the Ethereum ecosystem.º

   Given that it only takes one small flaw in smart
  contract code to instantly lock up or lose tens of millions of
  dollars, the EthTrust project’s standard and registry aim to make
  it quick and easy for organizations and individuals to tell if a
  smart contract has been through a full security audit by a
  professional team.

Besu + Docker 
@[https://besu.hyperledger.org/en/stable/HowTo/Get-Started/Installation-Options/Run-Docker-Image/]
@[https://hub.docker.com/r/hyperledger/besu/tags]

$º$ docker run hyperledger/besu:latestº

  $ docker run -p $JSON_RPC:8545 \   ←  run Besu in MainNet
    -p $localportWS:8546 \
    -p $localportP2P:30303  \
    hyperledger/besu:latest --rpc-http-enabled --rpc-ws-enabled
                            ^^^^^^^^^^^^^^^^^^
                            == -e BESU_RPC_HTTP_ENABLED=true
   ( --rpc-http-port, --p2p-port, --rpc-ws-port, --metrics-port,
     --graphql-http-port, and --metrics-push-port )

RºWARNº: Do not mount a volume at the default data path (/opt/besu).
        Mounting a volume at the default data path interferes with
        the operation of Besu and prevents Besu from safely launching.
        To run a node that maintains the node state (key and database),
        --data-path must be set to a location other than /opt/besu and
        a storage volume mounted at that location.

        --nat-method must be set to DOCKER or AUTO (vs NONE or UPNP).

Problems founds:
- Next error happens after closing besu:
  - First run works ok and a new database is generated properly.
    Then it is closed (through Docker kill -???)
  - Secont rund fails to restart with next exception:
    ... | main | INFO  | RocksDBKeyValueStorageFactory | Existing database detected at /
                                                         opt/besu/data. Version 0
 Rº picocli.CommandLine$ParameterException: org.rocksdb.RocksDBException:º     ← !!!!
 Rº You have to open all column families. Column families not opened: , , , ,º
        at org.hyperledger.besu.cli.BesuCommand.run(BesuCommand.java:1080)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1769)
        at picocli.CommandLine.access$900(CommandLine.java:145)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2141)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2108)
        at picocli.CommandLine$AbstractParseResultHandler.handleParseResult(CommandLine.java:1968)
        at picocli.CommandLine.parseWithHandlers(CommandLine.java:2322)
        ...
   It looks to be caused by non-clear close in Docker enviroments:
@[https://github.com/facebook/rocksdb/wiki/RocksJava-Basics#opening-a-database-with-column-families]
  RºWARNº: RocksDB is a native C++ library and there can be some JNI issue
Turbo Geth
@[https://eth.wiki/en/fundamentals/patricia-tree]
...  Turbo-geth is one implementation that gets to the root of the
problem: It flattens the trie database and uses the path of a node
(rather than its hash) as the [key, value] pair. This effectively
makes the depth of the tree irrelevant for lookups, and allows for a
variety of nifty features that can improve performance and reduce the
load on disk when running a full node.
SKALE framework
@[https://skale.network/]
@[https://skale.network/whitepaper] 
SKALE Network. An Ethereum Interoperable Elastic Blockchain Network
SKALE: Standard Kit for Asyncronous LEdgers.

- SKALE is a modular framework that splits blockchain consensus (BC)
  under asynchronous networking model into a sequence of stages. It
  then applies provably secure algorithms at each stage, so that the
  entire BC becomes provably secure. This modular framework allows to
  construct a wide variety of BCs with different tradeoffs as well as
  re-interpret and analyze security some of the existing BCs such as
  Tendermint.

Uniswap
"fully decentralized protocol for automated liquidity provision on Ethereum".
 Uniswap is a good example of use-case when ethers are controlled by Smart Contracts 
 (vs externally owned accounts).

• centralized vs de-centralized exchange:
  centralized exchange (Coinbase,...):
  - PRE-SETUP: register for an account.
  - exchange monitors and facilitates transactions.
  decentralized exchange (Coinbase,...):
  - PRE-SETUP: Connected crypto wallet to Uniswap's app (no third party involved)
  - no registration required. 
  - exchange operates as automated market maker offering various
    pairs of tokens to trade with prices set using mathematical formulas.

• Uniswap cryptocurrency:
  - high-risk "investment".
  - governance token to vote on proposed changes for the exchange.
  - if the exchange gets more popular, it will likely lead to more
    people wanting to buy the token.

• Implementation: 
  - Exchange uses liquidity pools, "drawing" from them when users trade.
                  └──────┬─────┘ 
                  ej:
                  ( crypto1, crypto 2) fund  ← e.g.: (ETH, DAI) pool
                  ( crypto1, crypto 3) fund 
                  ( crypto2, crypto 3) fund 
                  ...

  º##############º
  º# PRE-SETUP: #º
  º##############º
   User_A            → Uniswap_Dapp_S.C: Signed TX "Add liquidity" 
                                         (Lend equivalent amount of both cryptos to some Uniswap pool)
   Uniswap_Dapp_S.C  → Uniswap_Dapp_S.C: Add to pool.
                                          Pay share of the gas fees to user in that pool.

  º##################º
  º# SWAP Execution #º
  º##################º
   User_B            → Uniswap_Dapp_S.C: Signed TX with:
                                         - amount to trade  : N (owned) Ethers
                                         - Crytpo to receive: Dai

   Uniswap_Dapp_S.C  → Uniswap_Dapp_S.C: calculate Dai to be received 
   User_B            ← Uniswap_Dapp_S.C: Dai to be received
   User_B            → Uniswap_Dapp_S.C: confirm the trade
   Uniswap_Dapp_S.C  → Uniswap_Dapp_S.C: Pay from internal Ethereum/Dai pool 
                                         minus transaction (gas) fee, always 
                                         paid in Ethers. This fee is shared among
                                         users "feeding" the pool in the "PRESETUP".
                                         NOTE: Fees in Ethereum depend on the congestion of the network,
                                               not on the value of the transaction.
                                             RºUniswap is a poor choice for trading small swap amounts.º

• Alternatives (inspired by Uniswap) include: ( PancakeSwap , SushiSwap , BurgerSwap , Curve , DODO )
   - One advantage several other exchanges offer is that they run
     on the Binance Smart Chain, which currently has much lower fees than Ethereum.
     Particularly succesful is the case of PancakeSwap.

• Options to "invest" in Uniswap include:
  - buy it through an exchange like any other cryptocurrency (Coinbase, Gemini, Binance, ...)
  - trade for it on Uniswap exchange.


QuickSwap @[https://coinquora.com/quickswap-the-dex-curating-an-economical-and-scalable-way-to-swap-tokens/] "... The tradeoffs of a blockchain are passed on to the project’s building on top of them. This is what happened with Uniswap, the world’s first decentralized token swap platform. It was the first decentralized exchange (DEX) of the crypto space, which attracted the community for its decentralization and ability to process trades without asking its users to go through rigorous KYC/AML processes. However, with all of the advantages UniSwap offers, Rºits users suffer from high gas fees due to it being built on the Ethereum blockchain.º A simple transaction on Uniswap now often costs more than the transaction itself, leaving a gap that needed filling. BºQuickSwap was quick to address the issues plaguing Ethereum-based DEXs, by offering muchº Bºlower transaction fees and almost instant block formation time.º BºQuickSwap DES allows users to trade any ERC-20 tokens. Though the DEX is based on Ethereum,º Bºit is powered by the Polygon network, which provides several benefits not seen in otherº Bºsimilar solutions.º Bº For example, QuickSwap can trade any of the ERC-20 tokens listedº Bºon its platform with almost no gas costs and at lightning-fast º Bºspeeds, making QuickSwap (and Polygon) a great accompaniment for º BºUniSwap and Ethereum.º Moreover, anyone can list any ERC-20 token on QuickSwap by providing liquidity to enable token swaps. In return, the platform rewards them with a 0.3% transaction fee (out of which 0.25% goes to the LPs, 0.04% to the dragon’s lair (which is the QUICK staking pool), and 0.01% goes to QuickSwap’s treasury (to fund development). In addition to the trading fee, liquidity providers can earn QuickSwap’s native governance QUICK token – which they can use to create, vet, and vote on proposals relating to the running of the protocol. They can also use QUICK tokens to stake in the Dragon’s Lair to earn additional QUICK. • Reference Implementation: @[https://github.com/mudgen/quickswap-contracts/] By Nick Mudge ("Diamonds Standard")
EIP-165: Standard Interface

• NOTE: EIP-1820 improves over this standard, but EIP-165 is not 
  deprecated and still in active use (e.g, required by EIP-1155)
  as of 2021-10

• standard to publish and detect what interfaces a smart contract implements
  by detailing:

  - How interfaces are identified
  - How a contract will publish the interfaces it implements
  - How to detect if a contract implements ERC-165
  - How to detect if a contract implements any given interface

• ERC-165 in practice:
  
  
  ┌─ .../IERC165.sol interface ─────────────────────────────────────┐
  │ interface IERC165 {                                             │
  │     function supportsInterface(bytes4 interfaceId)              │
  │     external view returns (bool);                               │
  │ }                                                               │
  └─────────────────────────────────────────────────────────────────┘
 
 
  ┌─ ERC1155.sol implementation ─────────────────────────────────────┐
  │ import ".../utils/introspection/ERC165.sol";                     │
  │ import "./IERC1155.sol";                                         │
  │                                                                  │
  │ contract ERC1155 is IERC165, IERC1155, IERC1155MetadataURI {     │
  │     ...                                                          │
  │     function supportsInterface(bytes4 interfaceId)               │
  │     public view virtual                                          │
  │     override(IERC165)                                            │
  │     returns (bool) {                                             │
  │       return                                                     │
  │         interfaceId == type(IERC165).interfaceId             ||  │
  │         interfaceId == type(IERC1155).interfaceId            ||  │
  │         interfaceId == type(IERC1155MetadataURI).interfaceId ||  │
  │         super.supportsInterface(interfaceId);                    │
  │     }                                                            │
  │ }                                                                │
  └──────────────────────────────────────────────────────────────────┘

• See also:@[#eip_1820] Pseudo-introspection Registry Contract

EIP-1820: EIP-165"++"  
@[https://eips.ethereum.org/EIPS/eip-1820]
• Pseudo-introspection Registry Contract 
•ºStatus: Finalº
• It improves (but does NOT replaces) EIP-165.
• Superseed EIP-820 (universal registry)
Hapi One
@[https://www.hapi.one]

• On-Chain Cybersecurity Cross-Chain Protocol and Oracle
  data ─→ ML ─→ Oracle ─→ DAO

• Monitor for frauds, stolen-wallets, ...

• Works on Polygon.Network (cross-chain Ethereum compatible networks)
FireFly IoT Wallet
@[https://firefly.city/]
@[https://ethereum.stackexchange.com/questions/29524/sign-raw-transaction-offline-with-c-on-arduino]



You can use our Firefly Hardware Wallet (https://firefly.city) for the ATmega328 to do:

• secp256k1 signing
• RLP decoding transactions
• keccak256
• generating checksum addresses (or raw addresses)
• Signing requires in the neighbourhood of around 700 bytes of free memory,
  everything else requires a fairly slim memory footprint.
• Optional OLED display: Firefly source code also includes zero-memory video driver.
@[https://github.com/firefly/wallet/tree/master/source/libs/ethers]
Raiden Network
(Micro) Payment channels for Ethereum Network.
ZkOpru
@[https://github.com/zkopru-network/zkopru]
• Ethereum L2 scaling solution for private transactions using zk-SNARK and optimistic rollup. 
Non Classified / backlog
Aragon OS: Advanced deployment
@[https://aragon.one/]
@[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.
Aragon Connect @[https://aragon.org/connect] - toolkit for developers to seamlessly integrate DAO functionality into apps. - easy to use and blazing fast! - Ex 1: Obtain all the token holders (e.g. members) of a DAO const tokens = new TokenManager(await org.app({ appName: 'tokens.aragonpm.eth'})) const tokenDetails = await tokens.token() const tokenHolders = await tokenDetails.holders() - Ex 2: Get all votes (past and ongoing) of a DAO: const voting = new Voting(await org.app({ appName: 'voting.aragonpm.eth'})) const votes = await voting.votes() - Allow your user to vote on a proposal: const [path] = await org.appIntent( voting, 'vote', [votes[0].id, true, true] ). paths(wallet.account) for (const transaction of path.transactions) { await ethers.sendTransaction(transaction) }
GNOSIS Research
@[https://github.com/gnosis/research]

CREATE—Prediction Markets
- Whitepaper, ed. 22 Decmber 2017
- Any-order condition resolution in conditional prediction markets
- Apollo Prediction Market Framework Documentation

TRADE—Trading Protocols
- Batch Auction Optimization
- Batch auctions with uniform clearing price on Plasma
- Plasma SNAPP: Fully verified Plasma chain
- Plasma Research
- dFusion Specs
- DutchX: Fully decentralized auction based exchange
- DutchX Trading Protocol Documentation


HOLD—Multi-sig Wallets:
- Gnosis Safe Documentation
- Gnosis Safe Formal Verification
- Add wallet_ methods to improve dapp to wallet interaction
  "...  Interacting with smart contract based wallets is different to 
    the interaction with EOA based wallets. º The biggest difference is º
  º that smart contract based wallets cannot generate ECDSA signatures. º
  º Also smart contract based wallets provide the possibility for a lot º
  º of extended functionality º..."
py-libp2p
@[https://github.com/libp2p/py-libp2p]
- Python implementation of libp2p which will be used in Eth2.0 research,
  as well as in many other projects by UPenn seniors completing their capstone
  project (Zixuan Zhang, Robert Zajac, Alexander Haynes, and Aspyn Palatnick).
Forma Verification for Eth2.0 (Beacon Chain)
""" ...With my colleague Joanne Fuller, PhD at ConsenSys, we are 
  delighted to have released the first version of the formal 
  verification of the Eth2.0 (Beacon chain) specifications 
  https://lnkd.in/gw4JFf7q. This project was partially funded by a 
  grant from the Ethereum Foundation. ..."

@[https://github.com/ConsenSys/eth2.0-dafnypre]
@[https://cs.paperswithcode.com/paper/verification-of-the-incremental-merkle-tree]
  Verification of the Incremental Merkle Tree Algorithm with Dafny by Franck Cassez
• Who-is-Who:
  https://franck44.github.io/
  https://www.youtube.com/watch?v=pxe4qGwGBGg
   The Deposit Smart Contract (DSC) is an instrumental component of the
  Ethereum 2.0 Phase 0 infrastructure. We have developed the first
  machine-checkable version of the incremental Merkle tree algorithm
  used in the DSC. We present our new and original correctness proof of
  the algorithm along with the Dafny machine-checkable version. The
  main results are: 1) a new proof of total correctness; 2) a software
  artefact with the proof in the form of the complete Dafny code base
  and 3) new provably correct optimisations of the algorithm.
NuCypher
@[https://www.nucypher.com/]
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]
DeepSea
@[https://certik.org/deepsea_blockchain.html]
  Research at Yale and Columbia to further their work on DeepSEA,
  a formally verified language that compiles to the EVM.
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 ...
SandCastle_SQL
@[https://pegasys.tech/sandcastle-brings-sql-to-ethereum-smart-contracts/]
RºWARNº: Doesn't look to be continued.

  @[https://twitter.com/shahankhatch/status/1129427879262138369]
  |SQL| → |compiler| → |AST|  → |scopes    | → |code     | → |Solidity|
               ^                |validation|   |generator|
         ┌─────┴─────┐
         │           │
       |lexer|    |parser|
         ^           ^
         └─────┬─────┘
               │
       |parser-generator|
Optimistic VM (OVM)
@[https://medium.com/plasma-group/introducing-the-ovm-db253287af50]
• VM designed to support all layer 2 (L2) protocols.  
  It generality comes from a reframing of L2 as an "optimistic" fork 
  choice rule layered on top of Ethereum.
• ºThe formalization borrows heavily from CBC Casper researchº, and
  describes layer 2 as a direct extension to layer 1 consensus. This implies a
  possible unification of all “layer 2 scalability” constructions (Lightning,
  Plasma, etc) under a single theory and virtual machine: the OVM.

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]

• parity --help:
  Usage:
  parity [options]                                        Operating Options:
  parity ui [options]                                       --mode MODE
  parity dapp $path  [options]                              --mode-timeout SECS
  parity daemon $pid-file  [options]                        --mode-alarm SECS
  parity account (new | list ) [options]                    --auto-update SET
  parity account import $path... [options]                  --release-track TRACK
  parity wallet import $path --password FILE [options]      --no-download
  parity import [ $file  ] [options]                        --no-consensus
  parity export (blocks | state) [ $file  ] [options]       --force-direct
  parity signer new-token [options]                         --chain CHAIN
  parity signer list [options]                              -d --base-path PATH
  parity signer sign [ $id  ] [ --password FILE ] [options  --db-path PATH         ]
  parity signer reject $id  [options]                       --keys-path PATH
  parity snapshot $file  [options]                          --identity NAME
  parity restore [ $file  ] [options]
  parity tools hash $file
  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*
Parity Substrate
-  Designed to build custom blockchains for enterprises
   - Right privacy level for each use case
   - Light- client- first design for mobile applications and IoT
   - Forkless upgrade path to keep networks together
   - Multi-level permissioning
   - Encrypted transactions and state
   - Limiting to asynchronous calls optionality
   - Account-level locking
   - Governance tools and methods such as stakeholder referendums,
     approval voting, and qualified abstention biasing
- Architected on industry-standard WebAssembly  smart contracts
- Highly extensible Libp2p networking
- Rust-based primary implementation for speed and reliability
- Javascript secondary implementation for developability
Quorum-Maker
• Quorum-Maker:                             [devops][low_code]
@[https://github.com/synechron-finlabs/quorum-maker]
•RºWARN:º Abandoned project. Hyperledger Bevel (by Accenture) looks to replace it.

• Automation tool, wizard-like to bootstrap Quorum network of any number of
   nodes of various configurations dynamically with 
  reduced user input running on containers or Linux boxes. 
  • INSTALL PRE-REQUISITES)
    ✓ docker-CE ("Long Term Support") 
  • INSTALL)
    $º$ git clone https://github.com/synechron-finlabs/quorum-maker º
  • USSAGE)
    $º$ ./setup.sh --helpº

    join      Create a node and Join to existing Network
             --oip     IP address of the other(existing) node 
             --onm     Node Manager port of the other node
             --tip     IP address of this node (IP of the host machine)
             --whisper Discovery port of this node

    attach    Attach to existing Quorum Node ..
              --ip      IP address of existing Quorum
              --pk      Public Key of existing Constellation
              --whisper Discovery port of this node
              --active  Active attachment mode
              --passive Passive attachment mode

    create    Options:
              --ip        IP address of this node (IP of the host machine)
              --rpc       RPC port of this node
              --whisper   Discovery port of this node

    dev       (Create dev network)
              --project   Project Name
              --nodecount Number of nodes to be created
              --expose    Expose docker container ports (Optional)
              --tessera   Create node with Tessera Support (Optional)

    Common Options:
      --name    Name of the node to be created
      --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
      --tessera Create node with Tessera Support (Optional)
     --rpc     RPC port of this node

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

    $º$ ./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   º


    $º$ ./setup.sh attach -n slave1 --ip 10.0.2.15  \º
    $º --pk BULe... -r 22000 --whisper 21000        \º
    $º --constellation 9001 --raft 50401 --nm 11004 \º
    $º --active                                      º

    $º$ ./setup.sh dev -p TestNetwork -n 3           º