WEB3 FILE STORAGE
OPTIONS
IPFS
Filecoin
Arweave
WEB3 TECHNOLOGY STACK
THERE ARE SOME SMART CONTRACT
USE CASES WHERE STORAGE OF
LARGE AMOUNT OF DATA IS NEEDED
Gov Records Trade Finance
Title Recording Supply Chain
HOW EXPENSIVE IS IT TO STORE DATA
ON BLOCKCHIN?
(EXPERIMENT)
pragma solidity ^0.5.0;
contract WriteRandomData {
bytes32[] randomArray;
constructor() public {
bytes32 rand32 = keccak256(abi.encodePacked(block.timestamp));
for(uint i; i<32; i++) {
rand32 = keccak256(abi.encodePacked(rand32));
randomArray.push(rand32);
}
}
}
788,268 GAS UNITS TO CREATE
THE CONTRACT AND STORE 1KB
OF DATA
LET’S CREATE THE SAME CONTACT
BUT SKIP DATA STORAGE ON
BLOCKCHAIN
pragma solidity ^0.5.0;
contract WriteRandomData {
bytes32[] randomArray;
constructor() public {
bytes32 rand32 = keccak256(abi.encodePacked(block.timestamp));
for(uint i; i<32; i++) {
rand32 = keccak256(abi.encodePacked(rand32));
//randomArray.push(rand32);
}
}
}
73,032 GAS UNITS
LET’S CONVERT IT TO DOLLARS
AND CENTS
1 KB of data storage on Etherium: 788,268-73,032 = 715,236 Gas
Units
715,236 Gas Units = 715,236 Gwei (assuming that we set 1Gwei for
gas price)
1Gwei = 0.00001908 USD (as of 1/11/2020)
1KB Of storage: $0.00001908 * 715,236 = $ 13.64670288
(1/11/2020)
IPFS ON HIGH LEVEL: PEER-TO-
PEER NETWORK + GIT VERSIONING
Client-Server Network Peer-to-Peer Network
IPFS OBJECT
Data
< 256 kB of binary data
…
Link
Link
Name Hash Size
Link
MERKLE TREE
• Every leaf node is labelled with the
hash of a data block.
• Every non-leaf node is labelled with
the cryptographic hash of the labels
of its child nodes
MERKLE DIERECT ACCYCLIC
GRAPH (DAG)
DAG data structure similar to a Merkle tree but
not so strict:
1. DAG does not need to be balanced
2. Non-leaf nodes are allowed to contain data
Merkle DAG enables uniquely identified,
tamper-resistant and permanently stored
data shared by network nodes.
DAG creates a foundation for Distributed
Hash Table
IPFS PROPERTIES
With the Distributed Hash Table, nodes can store & share data
without central coordination
IPFS is Persistent Data Structure (nothing can be deleted)
Uploaded content is not guaranteed to persist on the network (all
participating nodes should consider participation a voluntary service)
HOW TO STORE AND ACCESS FILES
ON IPFS?
Command line interface https://dist.ipfs.io/#go-ipfs
API https://docs.ipfs.io/reference/api/http/
Libraries for different languages, for example, NPM module for JavaScript:
https://www.npmjs.com/package/ipfs-api
Web Gateway, for example:
https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu
Direct support from the browser, for example:
ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/wi
ki/Vincent_van_Gogh.html
IPFS Desktop application
IPFS DESKTOP
FILECOIN Filecoin (⨎) is an open-source, public
cryptocurrency and digital payment
system intended to be a blockchain-based
cooperative digital storage and data
retrieval method.
The blockchain is based on both proof-
of-replication and proof-of-spacetime.
Filecoin aims to store data in a
decentralized manner, which is resistant
to problems that occur in centralized
storage. Due to Filecoin's decentralized
nature, it protects the integrity of data's
location making it easily retrievable and
hard to censor.
FIL COIN
FILECOIN BENEFITS AND USE
CASES
A Storage Platform for NFTs (OpenSea)
Resilient to sensorship
Dependable Storage
Variable data
No need for API to store data for every provider
OpenSource
LOTUS
Lotus is the reference
implementation for the Filecoin
network
lotus client import 5gb-filecoin-payload.bin
lotus client deal
lotus wallet list
lotus client retrieve --miner f07709
mAVWg5AIgFw51hfKzfy8nRsKHlMtT8/DPBJhn1f9eFyOS
eldlAiE output-file
ARWEAVE CLAIMS
“Arweave enables you to store
documents and applications
forever”
“On top of the Arweave network lives the permaweb: a global, community-
owned web that anyone can contribute to or get paid to maintain”
“No more 404s. No more stealth edits. No more web apps that decline in
quality.”
THE LIBRARY OF ALEXANDRIA
PERMAWEB VS TRADITIONAL WEB
(TC VIEW)
ARWEAVE ECOSYSTEM
AR
ARWEAVE
Protocol
Viewblock.i
o
Explorer
ArDrive
Permanent Data
Storage for Everyone
BIG PICTURE
EXPLORER
AR TOKEN
ARDRIVE
ArDrive is based on a one-time fee
for permanent use, and the storage
price is about $20 for 1G data
ArDrive is the storage client of Arweave
SOME OF THE APPLICATIONS TO
EXPLORE
Weavemail https://ubehghhbg2r5xglof2hplra2w44gehwxgyi5cqiy
eqo2q6yk7kha.arweave.net/oEhzHOE2o9uZbi6O9cQat
zhiHtc2EdFBGCQdqHsK-o4
Forum https://5vbgactgfkjm.arweave.net/3SMZ1RW2xGTBdTi
UznKrkTJTHtYtBs27wm0q2H58Jck#/forum/About%20t
he%20Forum
ArDrive https://ardrive.io/
APPLICATIONS THAT USE ARWEAVE
MORE INFORMATION ABBOUT
ARWEAVE AND PERMAWEB
https://docs.arweave.org/info/
https://techcrunch.com/2019/11/05/how-arweave-permaweb-
works/
https://docs.arweave.org/info/mining/mining-guide
QUESTIONS
STAY IN TOUCH
Gene Leybzon https://www.linkedin.com/in/leybzon/
https://www.meetup.com/members/90744
20/
https://www.leybzon.com
INSTALLING IPFS • Installing IPFS Node on
GCP from scratch
CLOUD CONSOLE, CREATE A NEW
INSTANCE
https://console.cloud.google.com/
OPEN PORT 4001
SSH INTO NEW INSTANCE
INSTALL GO
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt-get update
sudo apt-get install golang-go
go version
INSTALL IPFS
go get -u -d github.com/ipfs/go-ipfs
cd ~/go/src/github.com/ipfs/go-ipfs
START IPFS NODE
cd ~/go/bin
./ipfs init
./ipfs daemon
PUBLISHING TO IPFS
• How to publish files to
the IPFS node
• How to read objects
from IPFS node
PUBLISH A FILE
leybzon@instance-1:~/go/bin$ cd ~
leybzon@instance-1:~$ vi test.html
leybzon@instance-1:~$ ./go/bin/ipfs add -w test.html
added QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP5CcT1zk
test.html
added QmeoBZA3ywRT5wEa6RBuHxF4qaKAK8qSxuxWCr4BpPzT2r 7 B
/ 7 B
[=========================================]
100.00%
CHECK THAT THE FILE WAS
PUBLISHED LOCALLY
leybzon@instance-1:~/go/bin$ ./go/bin/ipfs object get
QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP5CcT1
zk{"Links":[],"Data":"u0008u0002u0012u0007testnnnu0018u0007"}u0
012u0007testnnnu0018u0007"}
START IPFS DAEMON
leybzon@instance-2:~/go/bin$ ~/go/bin/ipfs daemon
Initializing daemon...go-ipfs version: 0.5.0-dev-049d3b0Repo version: 7
System version: amd64/linuxGolang version: go1.13.4
Swarm listening on /ip4/10.128.0.5/tcp/4001
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /p2p-circuit
Swarm announcing /ip4/10.128.0.5/tcp/4001
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
WebUI: http://127.0.0.1:5001/webui
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready
USE INFURA GATEWAY TO GET THE
OBJECT
leybzon@instance-1:~/go/bin$ curl
“https://ipfs.infura.io:5001/api/v0/cat?arg=QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP
5CcT1zk”
test
SMART CONTRACT +
IPFS
• How to use IPFS objects in
Smart Contracts
• Creating ERC721 Smart
Contract
• Minting tokens connected
to IPFS objects
ERC-721 NFT CONNECTED TO DATA
IPFS
NFT Tokens are
 Unique
 Irreplaceable
 Non-
interchngable
ERC721Full ERC721Mintable
ERC721
ERC721Enumerabl
e
ERC721Metadata
MyNFT
mint1()
mintUniqueTokenT
ERC721 SMART CONTRACT 1/2
pragma solidity ^0.5.0;
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol';
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol';
contract MyNFT is ERC721Full, ERC721Mintable {
constructor() ERC721Full("IPFS", "IPFS_DEMO") public {
}
event RecordedIpfsHash(uint256, string);
mapping(uint256 => string) _documents;
function mint1(uint256 _uid, string memory _ipfsHash) public{
_mint(msg.sender, _uid);
_documents[_uid] = _ipfsHash;
emit RecordedIpfsHash(_uid, _ipfsHash);
}
ERC721 SMART CONTRACT 2/2
…
function mintUniqueTokenTo(
address _to,
uint256 _tokenId,
string memory _tokenURI,
string memory _ipfsHash
) public
{
super._mint(_to, _tokenId);
super._setTokenURI(_tokenId, _tokenURI);
_documents[_tokenId] = _ipfsHash;
emit RecordedIpfsHash(_tokenId, _ipfsHash);
}
}
DEPLOYING SMART CONTRACT TO
BLOCKCHAIN
CALLING SMART CONTRACT TO
ISSUE NEW TOKEN
VERIFYING THAT THE TOKEN WAS
CREATED SUCCESSFULLY

Web3 File Storage Options

  • 1.
  • 2.
  • 3.
    THERE ARE SOMESMART CONTRACT USE CASES WHERE STORAGE OF LARGE AMOUNT OF DATA IS NEEDED Gov Records Trade Finance Title Recording Supply Chain
  • 4.
    HOW EXPENSIVE ISIT TO STORE DATA ON BLOCKCHIN? (EXPERIMENT) pragma solidity ^0.5.0; contract WriteRandomData { bytes32[] randomArray; constructor() public { bytes32 rand32 = keccak256(abi.encodePacked(block.timestamp)); for(uint i; i<32; i++) { rand32 = keccak256(abi.encodePacked(rand32)); randomArray.push(rand32); } } }
  • 5.
    788,268 GAS UNITSTO CREATE THE CONTRACT AND STORE 1KB OF DATA
  • 6.
    LET’S CREATE THESAME CONTACT BUT SKIP DATA STORAGE ON BLOCKCHAIN pragma solidity ^0.5.0; contract WriteRandomData { bytes32[] randomArray; constructor() public { bytes32 rand32 = keccak256(abi.encodePacked(block.timestamp)); for(uint i; i<32; i++) { rand32 = keccak256(abi.encodePacked(rand32)); //randomArray.push(rand32); } } }
  • 7.
  • 8.
    LET’S CONVERT ITTO DOLLARS AND CENTS 1 KB of data storage on Etherium: 788,268-73,032 = 715,236 Gas Units 715,236 Gas Units = 715,236 Gwei (assuming that we set 1Gwei for gas price) 1Gwei = 0.00001908 USD (as of 1/11/2020) 1KB Of storage: $0.00001908 * 715,236 = $ 13.64670288 (1/11/2020)
  • 9.
    IPFS ON HIGHLEVEL: PEER-TO- PEER NETWORK + GIT VERSIONING Client-Server Network Peer-to-Peer Network
  • 10.
    IPFS OBJECT Data < 256kB of binary data … Link Link Name Hash Size Link
  • 11.
    MERKLE TREE • Everyleaf node is labelled with the hash of a data block. • Every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes
  • 12.
    MERKLE DIERECT ACCYCLIC GRAPH(DAG) DAG data structure similar to a Merkle tree but not so strict: 1. DAG does not need to be balanced 2. Non-leaf nodes are allowed to contain data Merkle DAG enables uniquely identified, tamper-resistant and permanently stored data shared by network nodes. DAG creates a foundation for Distributed Hash Table
  • 13.
    IPFS PROPERTIES With theDistributed Hash Table, nodes can store & share data without central coordination IPFS is Persistent Data Structure (nothing can be deleted) Uploaded content is not guaranteed to persist on the network (all participating nodes should consider participation a voluntary service)
  • 14.
    HOW TO STOREAND ACCESS FILES ON IPFS? Command line interface https://dist.ipfs.io/#go-ipfs API https://docs.ipfs.io/reference/api/http/ Libraries for different languages, for example, NPM module for JavaScript: https://www.npmjs.com/package/ipfs-api Web Gateway, for example: https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu Direct support from the browser, for example: ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/wi ki/Vincent_van_Gogh.html IPFS Desktop application
  • 15.
  • 16.
    FILECOIN Filecoin (⨎)is an open-source, public cryptocurrency and digital payment system intended to be a blockchain-based cooperative digital storage and data retrieval method. The blockchain is based on both proof- of-replication and proof-of-spacetime. Filecoin aims to store data in a decentralized manner, which is resistant to problems that occur in centralized storage. Due to Filecoin's decentralized nature, it protects the integrity of data's location making it easily retrievable and hard to censor.
  • 17.
  • 18.
    FILECOIN BENEFITS ANDUSE CASES A Storage Platform for NFTs (OpenSea) Resilient to sensorship Dependable Storage Variable data No need for API to store data for every provider OpenSource
  • 19.
    LOTUS Lotus is thereference implementation for the Filecoin network lotus client import 5gb-filecoin-payload.bin lotus client deal lotus wallet list lotus client retrieve --miner f07709 mAVWg5AIgFw51hfKzfy8nRsKHlMtT8/DPBJhn1f9eFyOS eldlAiE output-file
  • 20.
    ARWEAVE CLAIMS “Arweave enablesyou to store documents and applications forever” “On top of the Arweave network lives the permaweb: a global, community- owned web that anyone can contribute to or get paid to maintain” “No more 404s. No more stealth edits. No more web apps that decline in quality.”
  • 21.
    THE LIBRARY OFALEXANDRIA
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
    ARDRIVE ArDrive is basedon a one-time fee for permanent use, and the storage price is about $20 for 1G data ArDrive is the storage client of Arweave
  • 28.
    SOME OF THEAPPLICATIONS TO EXPLORE Weavemail https://ubehghhbg2r5xglof2hplra2w44gehwxgyi5cqiy eqo2q6yk7kha.arweave.net/oEhzHOE2o9uZbi6O9cQat zhiHtc2EdFBGCQdqHsK-o4 Forum https://5vbgactgfkjm.arweave.net/3SMZ1RW2xGTBdTi UznKrkTJTHtYtBs27wm0q2H58Jck#/forum/About%20t he%20Forum ArDrive https://ardrive.io/
  • 29.
  • 30.
    MORE INFORMATION ABBOUT ARWEAVEAND PERMAWEB https://docs.arweave.org/info/ https://techcrunch.com/2019/11/05/how-arweave-permaweb- works/ https://docs.arweave.org/info/mining/mining-guide
  • 31.
  • 32.
    STAY IN TOUCH GeneLeybzon https://www.linkedin.com/in/leybzon/ https://www.meetup.com/members/90744 20/ https://www.leybzon.com
  • 33.
    INSTALLING IPFS •Installing IPFS Node on GCP from scratch
  • 34.
    CLOUD CONSOLE, CREATEA NEW INSTANCE https://console.cloud.google.com/
  • 35.
  • 36.
    SSH INTO NEWINSTANCE
  • 37.
    INSTALL GO sudo add-apt-repositoryppa:longsleep/golang-backports sudo apt-get update sudo apt-get install golang-go go version
  • 38.
    INSTALL IPFS go get-u -d github.com/ipfs/go-ipfs cd ~/go/src/github.com/ipfs/go-ipfs
  • 39.
    START IPFS NODE cd~/go/bin ./ipfs init ./ipfs daemon
  • 40.
    PUBLISHING TO IPFS •How to publish files to the IPFS node • How to read objects from IPFS node
  • 41.
    PUBLISH A FILE leybzon@instance-1:~/go/bin$cd ~ leybzon@instance-1:~$ vi test.html leybzon@instance-1:~$ ./go/bin/ipfs add -w test.html added QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP5CcT1zk test.html added QmeoBZA3ywRT5wEa6RBuHxF4qaKAK8qSxuxWCr4BpPzT2r 7 B / 7 B [=========================================] 100.00%
  • 42.
    CHECK THAT THEFILE WAS PUBLISHED LOCALLY leybzon@instance-1:~/go/bin$ ./go/bin/ipfs object get QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP5CcT1 zk{"Links":[],"Data":"u0008u0002u0012u0007testnnnu0018u0007"}u0 012u0007testnnnu0018u0007"}
  • 43.
    START IPFS DAEMON leybzon@instance-2:~/go/bin$~/go/bin/ipfs daemon Initializing daemon...go-ipfs version: 0.5.0-dev-049d3b0Repo version: 7 System version: amd64/linuxGolang version: go1.13.4 Swarm listening on /ip4/10.128.0.5/tcp/4001 Swarm listening on /ip4/127.0.0.1/tcp/4001 Swarm listening on /ip6/::1/tcp/4001 Swarm listening on /p2p-circuit Swarm announcing /ip4/10.128.0.5/tcp/4001 Swarm announcing /ip4/127.0.0.1/tcp/4001 Swarm announcing /ip6/::1/tcp/4001 API server listening on /ip4/127.0.0.1/tcp/5001 WebUI: http://127.0.0.1:5001/webui Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080 Daemon is ready
  • 44.
    USE INFURA GATEWAYTO GET THE OBJECT leybzon@instance-1:~/go/bin$ curl “https://ipfs.infura.io:5001/api/v0/cat?arg=QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP 5CcT1zk” test
  • 45.
    SMART CONTRACT + IPFS •How to use IPFS objects in Smart Contracts • Creating ERC721 Smart Contract • Minting tokens connected to IPFS objects
  • 46.
    ERC-721 NFT CONNECTEDTO DATA IPFS NFT Tokens are  Unique  Irreplaceable  Non- interchngable ERC721Full ERC721Mintable ERC721 ERC721Enumerabl e ERC721Metadata MyNFT mint1() mintUniqueTokenT
  • 47.
    ERC721 SMART CONTRACT1/2 pragma solidity ^0.5.0; import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol'; import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol'; contract MyNFT is ERC721Full, ERC721Mintable { constructor() ERC721Full("IPFS", "IPFS_DEMO") public { } event RecordedIpfsHash(uint256, string); mapping(uint256 => string) _documents; function mint1(uint256 _uid, string memory _ipfsHash) public{ _mint(msg.sender, _uid); _documents[_uid] = _ipfsHash; emit RecordedIpfsHash(_uid, _ipfsHash); }
  • 48.
    ERC721 SMART CONTRACT2/2 … function mintUniqueTokenTo( address _to, uint256 _tokenId, string memory _tokenURI, string memory _ipfsHash ) public { super._mint(_to, _tokenId); super._setTokenURI(_tokenId, _tokenURI); _documents[_tokenId] = _ipfsHash; emit RecordedIpfsHash(_tokenId, _ipfsHash); } }
  • 49.
  • 50.
    CALLING SMART CONTRACTTO ISSUE NEW TOKEN
  • 51.
    VERIFYING THAT THETOKEN WAS CREATED SUCCESSFULLY

Editor's Notes

  • #3 Diagram from https://blog.coinbase.com/a-simple-guide-to-the-web3-stack-785240e557f0
  • #4 https://www.ccn.com/smart-contracts-12-use-cases-for-business-and-beyond/
  • #6 https://kovan.etherscan.io/tx/0x878fea422658c0226cae626303aa814f7016fb0bbaca8f96a87b913e7975b634
  • #8 https://kovan.etherscan.io/tx/0xae695b8748620d89d08f7480723138de1cffdc39a40c6d72e210a681cab1fc27
  • #9 https://ethgasstation.info/
  • #10 https://en.wikipedia.org/wiki/BitTorrent
  • #11 https://medium.com/@ConsenSys/an-introduction-to-ipfs-9bba4860abd0
  • #12 https://en.wikipedia.org/wiki/Merkle_tree every leaf node is labelled with the hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes
  • #13 https://en.wikipedia.org/wiki/Merkle_tree every leaf node is labelled with the hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes Image from https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSG4yZSyyw91ZphCLwGfIu2cyP3bD2GEu8uy2FQXX1vvFEvkQqn&s
  • #16 Demo
  • #18 https://coinmarketcap.com/currencies/filecoin/
  • #21 https://www.arweave.org/ https://arwiki.wiki/#/en/main
  • #22 https://21h007.wordpress.com/2018/12/11/the-library-of-alexandria/
  • #23 https://techcrunch.com/2019/11/05/how-arweave-permaweb-works/
  • #24 https://www.arweave.org/ https://arwiki.wiki/#/en/main
  • #26 https://viewblock.io/arweave/stats
  • #27 https://www.coingecko.com/en/coins/arweave
  • #35 https://console.cloud.google.com/ https://console.cloud.google.com/compute/instances?project=pbs-network-test&instancessize=50 “Create Instance” Select Ubuntu as boot disk
  • #36 https://console.cloud.google.com/networking/firewalls/add?project=pbs-network-test&authuser=0&hl=en
  • #43 ./go/bin/ipfs object get <hash> ./go/bin/ipfs cat <hash>
  • #44 ~/go/bin/ipfs daemon
  • #45 https://ipfs.infura.io:5001/api/v0/cat?arg=QmaqZ2DhwyxRFuYFrE3wxRwXCeRjZL1F8R5yxTfAUNE2Tx ./go/bin/ipfs cat QmaqZ2DhwyxRFuYFrE3wxRwXCeRjZL1F8R5yxTfAUNE2Tx
  • #47 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721Full.sol https://github.com/leybzon/solidity-baby-steps/blob/master/contracts/79_ERC_721_IPFS.sol
  • #48 https://github.com/leybzon/solidity-baby-steps/blob/master/contracts/79_ERC_721_IPFS.sol
  • #49 https://github.com/leybzon/solidity-baby-steps/blob/master/contracts/79_ERC_721_IPFS.sol
  • #50 POST to https://{{blockchain}}.apidapp.com/1/contract
  • #51 Calling mintUniqueTokenTo({{id}},{{$randomInt}}{{$randomInt}},{{$randomString}},'QmTBJ2SCD5Jpkqu3eM6utx4yfviwHBNKGqFgfbP5CcT1zk')
  • #52 https://kovan.etherscan.io/tx/0x09998673de181648fbd06ee732e8e10ea00810cfbcc3aac8c8dee8e1b39883a0