From 6f5ad9deffcf52fcf006c33fdd3f448039aab365 Mon Sep 17 00:00:00 2001 From: elviejo79 Date: Wed, 3 Feb 2021 22:37:18 -0600 Subject: [PATCH 01/99] Glow tutorial --- .../auction.png | Bin 0 -> 88344 bytes .../ballot.png | Bin 0 -> 35850 bytes .../buy_sig.png | Bin 0 -> 36295 bytes .../coinflip.png | Bin 0 -> 42010 bytes .../deadmanswitch.png | Bin 0 -> 75906 bytes .../rps-min.png | Bin 0 -> 56679 bytes ...02-03_07-00-00_learning-glow-by-example.md | 690 ++++++++++++++++++ 7 files changed, 690 insertions(+) create mode 100644 resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png create mode 100644 resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/ballot.png create mode 100644 resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/buy_sig.png create mode 100644 resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png create mode 100644 resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png create mode 100644 resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md diff --git a/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png b/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png new file mode 100644 index 0000000000000000000000000000000000000000..ccde64e050bf730c0f3b7effe5a28793ed5ce000 GIT binary patch literal 88344 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%0Dt&BJlvyL5uNHQV-Jbp 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 TRTx9p-G~cIBeNeo@%X<0q-mSH literal 0 HcmV?d00001 diff --git a/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png b/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png new file mode 100644 index 0000000000000000000000000000000000000000..6e9a5d57032c909a43ba2c3089bdb9e9f78f392b GIT binary patch literal 42010 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

nQ9 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 What's going to happen? +> The winners are going to do what worked at Bell Labs in 1978: +> build a programming language, like C, that's portable and efficient. +> It should compile down to "native" code (native code being JavaScript and DOMs) +> with different backends for different target platforms, +> where the compiler writers obsess about performance so you don't have to. +> – Joel Spolsky: [Strategy Letter VI](https://www.joelonsoftware.com/2007/09/18/strategy-letter-vi/) + +We are probably at the same crossroads in smart contract development technology. +As Joel puts it, the "winners" are going to be the ones that create a portable language. +In that regard, Glow is a programming language tailored to the challenges of smart contract development, +so that you don't have to worry about the low-level details of the blockchain implementation. +It takes ReasonML's syntax (itself a safe subset of javascript), +couples it with a powerful compiler that has added support for: + +- Game-Theoretic Safety +- Asynchronous communication +- Multi-Party Computation +- Consensual Asset Control + +To create a language in which describing smart contracts is *easy and safe*. + +In this article, we are going to analyze the glow sample programs provided in the distribution to learn +How they work, and how could we apply them to our own needs. + + +# Buy Signature ([buysig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? + +Let's imagine you want to have your Testament notarized. What would you do? + +> Probably you will write your Testament, +> And pay a Notary to stamp it, +> and store a copy for future reference. + +If we think about it, there are many interactions in the world that follow that same process: + +- When you have your diploma certified by your university. +- When you renew your Driver's license, there is no test, just a new stamp on it. + +We could generalize the process as: + +> A Buyer (you in this case) +> Pays a Seller +> Takes something, or better yet, a representation of the thing, a Digest +> to a Seller. +> So that the Seller Signs the Digest. +> And everyone can see that the Digest was Signed. + +Well this is the interaction that the `buy_sig.glow` contract codifies. + + +## Visualizing the Buyer / Seller interactions + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/buy_sig.png) + + +## Glow code + + 1 #lang glow + 2 @interaction([Buyer, Seller]) + 3 let payForSignature = (digest : Digest, price : Assets) => { + 4 deposit! Buyer -> price; + 5 @verifiably(Seller) let signature = sign(digest); + 6 publish! Seller -> signature; + 7 verify! signature; + 8 withdraw! Seller <- price; + 9 } + +2. Buyer and Seller have agreed to the terms of this sale. Know what the signature is about, and they want to conduct this sale. +3. The Digest of the message to sign is a parameter of the interaction, as is the convened price. +4. The Buyer deposits the money according to the price. +5. Seller signs. But it's private only to the Seller +6. The signature is made for public for everyone to see. +7. the signature is verified by everyone in a way that the contract enforces. +8. Finally, the money is transferred to the Seller. + +There several things to notice: + +1. The code looks a lot like the sequence diagram we created before +2. The lines of code with @Seller annotation are private. +3. The language itself takes care of requirements. If the Buyer never deposits, then the Seller never will be able to sign. + + +## Lessons learned + +- Identify the participants of a contract with `@interaction` + +When an instruction is annotated with the participant's name, that value is private for the participant. Like `@verifiably(Seller)` + +- There are clear instructions for `deposit!` and `withdraw!` + + +# How can we flip a coin in Glow? (coinflip.glow) + +Flipping a coin is a game as old as, well, coins. +Alice throws the coin *in the air*, +And Bob calls whatever he thinks is going to come out. +And the loser pays the winner. Whatever the amount was. + +However, in the blockchain, there is no such thing as *in the air*. +So how could we have something random that has a 50 / 50 chance for Alice? + +For example, Alice flips her coin. +Bob flips his coin +And then Alice wins if both coins match. +Or Bob wins if the coins are different. +Both outcomes have a 50 / 50 chance of happening. + + +## Sequence diagram + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png) + + +## Glow code + +So to represent the previous interaction in Glow. + + 1 #lang glow + 2 @interaction([A, B]) + 3 let coinFlip = (wagerAmount) => { + 4 @A assert! canReach(A_wins); + 5 @A let randA = randomUInt256(); + 6 @verifiably(A) let commitment = digest(randA); + 7 publish! A -> commitment; deposit! A -> wagerAmount; + 8 @B assert! canReach(B_wins); + 9 @B let randB = randomUInt256(); + 10 publish! B -> randB; deposit! B -> wagerAmount; + 11 publish! A -> randA; + 12 verify! commitment; + 13 if (((randA ^^^ randB) &&& 1) == 0) { + 14 A_wins: withdraw! A <- 2*wagerAmount + 15 } else { + 16 B_wins: withdraw! B <- 2*wagerAmount + 17 } + 18 }; + +1. Every glow program starts with the #lang glow identification +2. We know that two actors, A and B (Alice and Bob), are going to participate in this contract +3. coinFlip requires to know the amount each player is going to bet to get started. +4. Alice needs to be assured that there is a state where she can win. Ie. `assert!` makes sure that the program can reach the label `A_wins` +5. Alice draws random numbers between 0 and 2256. Approx. 78 decimal digits. +6. Alice stores in the commitment value the Digest of the random number she generated. +7. She publishes her commitment in the blockchain and deposits her wager. + +Now is Bob's turn + +8. Bob makes sure that it's possible to get to the `B_wins` label to know that he can win. +9. Bob flips a coin. i.e., Draw a random number between 0 and 2256. +10. Bob publishes the coin that he flipped and deposits his wager +11. Alice publishes the coin that she threw. +12. We `verify!` that the commitment matches the coin that she threw. +13. By doing a bitwise XOR of the random numbers thrown by Alice and Bob, we find that they match +14. Alice wins and withdraws two times the wager +15. but, If the `xor` doesn't match, Bob wins and +16. Gets double the bet. + + +## Lessons learned + +- You can generate random numbers with `randomUInt256` +- You can `assert!` you can reach a label such as `A_wins:` +- There are bitwise operations with like `^^^` and `&&&` + + +# Playing Rock, Paper, Scissors (rps-min.glow)? + +Rock, Paper, Scissors is the classic children game where both kids show at the same time what they have picked. +And decide who won based on the following rules: + +- Both selected the same: Draw +- Rock beats Scissors +- Paper beats Rock +- Scissors beats Paper + +But how con we codify this in Glow if there is not at the *same time*. +And How a player communicates its pick to the blockchain during the game? + + +## Visualization + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png) + + +## Glow code + + 1 #lang glow + 2 data Hand = | Rock | Paper | Scissors; + 3 data Outcome = | B_Wins | Draw | A_Wins; + 4 let winner = (handA : Hand, handB : Hand) : Outcome => { + 5 Outcome.ofNat((Hand.toNat(handA) + (4 - Hand.toNat(handB))) % 3) } + 6 + 7 @interaction([A, B]) + 8 let rockPaperScissors = (wagerAmount) => { + 9 @A assert! canReach(end, end.outcome == A_Wins); + 10 @A let handA = Hand.input("First player, pick your hand"); + 11 @A let salt = randomUInt256(); + 12 @verifiably(A) let commitment = digest([salt, handA]); + 13 publish! A -> commitment; deposit! A -> wagerAmount; + 14 + 15 @B assert! canReach(end, end.outcome == B_Wins); + 16 @B let handB = Hand.input("Second player, pick your hand"); + 17 publish! B -> handB; deposit! B -> wagerAmount; + 18 + 19 publish! A -> salt, handA; + 20 verify! commitment; + 21 let outcome = winner(handA, handB); + 22 end: switch(outcome) { + 23 | A_Wins => withdraw! A <- 2*wagerAmount + 24 | B_Wins => withdraw! B <- 2*wagerAmount + 25 | Draw => withdraw! A <- wagerAmount; withdraw! B <- wagerAmount }} + +2. A `Hand` can only be `Rock, Paper or Scissors` +3. There are only three possible `Outcome` either `B_wins`, `A_wins` or its a `Draw` +4. Now define a function `winner`, that given two hands can determine the `Outcome` +5. This is an arithmetic trick that translates each of the nine possible hand combinations to three possible outcomes +6. + +7. Alice and Bob use this contract +8. Declare the `rockPaperScissors` contract that has the `wagerAmount` +9. `@Alice` makes sure (`assert!`) that it's possible to reach the `end:` label +10. `@Alice` asks (`input`) and stores the value of her Hand. +11. `@Alice` creates a random value (`salt`) that will be used to obfuscate her Hand +12. `@Alice` store the obfuscated value of her Hand in a `verifiably` commitment +13. `@Alice` makes her commitment public and `deposit!` her wage. +14. + +15. `@Bob` makes sure he can reach the `end.outcome` where he wins +16. `@Bob` can `input` what hand he chooses to play +17. `@Bob` publishes his Hand and deposits his wager +18. + +19. Now it's possible to publish the `salt` and in the next step, use it to +20. `verify!` that the `commitment` was obfuscated with the salt +21. now we calculate the `outcome` as the result of evaluating the `winner` function with both hands. +22. `switch` for pattern matching, it's possible to select the appropriate outcome. +23. if `outcome` is `A_wins` `withdraw` to Alice both wages. +24. if `outcome` is `B_wins` `withdraw` to Bob both wages. +25. if `outcome` is `Draw` `withdraw` to give back their money to Alice and Bob. + + +## Lessons learned + +- You can define your data types with `data Hand` +- You can define smaller functions that are used later in the contract. Like: `let winner = (handA:Hand, handB:Hand)` +- You can use `switch` to do pattern matching + + +# How to create a deadman switch works? + +Let's suppose a millionaire uncle is about to die, +and he has called for you because he will give you the password to all his fortune. +However, while you are traveling to see your dear uncle; +He passes away, and only he knew the password for the safe! + +Heartbroken because of the loss of your uncle, you return to a boring job. + +However, six months later, you get an email with the password for the safe! +It turns out your uncle had a *dead man switch* that would automatically reveal the password. + +You knew it! Your uncle always was super smart. + +In this contract, we are going to see how your uncle implemented that contract in Glow. + + +## Visualization + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png) + + +## Glow Code + + 1 #lang glow + 2 // -*- JavaScript -*- + 3 // Inspired by https://github.com/KarolTrzeszczkowski/Electron-Cash-Last-Will-Plugin + 4 + 5 data Command = Withdraw(x : Nat) | Inherit(x : Nat) + 6 + 7 @interaction([Owner, Heir]) + 8 let deadManSwitch = (expirationDelay) => { + 9 let rec loop = (expirationTimestamp) => + 10 choice { + 11 | @_ deposit! x ; + 12 loop (expirationtimestamp); + 13 | @owner publish! withdraw(x); + 14 withdraw! owner <- x ; + 15 loop (now() + expirationdelay); + 16 | @heir publish! inherit(x); + 17 require! now() >= expirationtimestamp; + 18 withdraw! heir <- x; + 19 }; + 20 loop(now() + expirationdelay); + 21 } + +- 5 on this contract, there are only two actions, either withdraw or inherit. +- 7 and there are only two participants, the Owner of the fortune and you. +- 8 When creating the contract, the Owner must say how often he wants it to renew. For example, every six months. +- 20 The first time we go into the loop, it starts +- 9 Now the `loop` is a function that can call itself (recursive). +- 10 Is like pattern matching but based on whom performs the action +- 11 If there is a deposit, the contract continues. +- 13 In order to show that it's still alive, the Owner publishes on the blockchain that he wants to withdraw a little bit of the funds in the contract. +- 15 It renews the *dead man switch* with a new deadline. +- 16 When the `@heir` signals on the blockchain that is ready to inherit. + +The contract checks if the current block is over the expiration day. +If it is, releases the funds to the `heir`. + + +## Lessons learned + +- How to use explicit timestamps +- How to use recursive functions + + +# How does the Simple Auction (auction.glow) contract work? + +Imagine an auction like in the movies where each one of the bidders tries to outbid the previous one. +However, in a blockchain auction, each bidder has to put the money first in order to get to be the top bidder. +And then they get their money back when they are outbid. + + +## Visualization + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png) + + +## Glow code + + 1 #lang glow + 2 data Action = Bid(TokenAmount) | BuyItNow | Close; + 3 + 4 @interaction([Seller]) + 5 let simpleAuction = (goods : Assets, expirationTime : Timestamp, buyItNowPrice: TokenAmount) => { + 6 require! Assets.is_positive(goods); + 7 require! expirationTime > currentTime(); + 8 deposit! Seller -> goods; + 9 + 10 @interaction([Seller, CurrentBidder]) + 11 let rec auction = (currentBid) => { + 12 assert! @deposited == goods + currentBid; + 13 choice { + 14 | ForAllParticipant (NewBidder) { + 15 @NewBidder bid = Bid(input(["Enter next bid"], TokenAmout)); + 16 publish! NewBidder -> bid ; deposit! NewBidder -> bid; + 17 @NewBidder assume! @value(goods) > @value(bid); + 18 require! currentTime() < expirationTime; + 19 require! bid > currentBid; + 20 require! bid < buyItNowPrice; + 21 withdraw! CurrentBidder <- currentBid; + 22 @interaction([Seller, NewBidder]) auction(bid); + 23 | ForAllParticipant (NewBidder) { + 24 publish! NewBidder -> BuyItNow ; deposit! NewBidder -> buyItNowPrice; + 25 require! currentTime() < expirationTime; + 26 withdraw! NewBidder <- goods; + 27 withdraw! CurrentBidder <- currentBid; + 28 withdraw! Seller <- buyItNowPrice; + 29 | @_ { publish! Close; } => + 30 require! currentTime() >= expirationTime; + 31 withdraw! Seller <- currentBid; + 32 withdraw! CurrentBidder <- goods; + 33 }; + 34 @interaction([Seller, Seller]) auction(0); + 35 } + +- 2 Declares the possible commands that could be performed on this contract +- 4 Only the Seller can create an auction +- **5:** In order to create an auction, a Seller must provide: + +the `Goods` that could be anything that can be codified as an asset, +an `expirationTime` at which point the auction is over and +a price to buy it immediately `buyItNowPrice`. + +- 8 The Seller must deposit the goods in the smart contract. This could, for example, a photograph. +- 34 The real auction begins at 0, and the "first bidder" is the Seller himself. +- 10 The real auction is an interaction between the Seller and the Current bidder. +- 11 This function is recursive, so it can call itself. +- 12 A sanity check, let's make sure that the amount deposited to the contract is the goods plus the current bidder. +- 14 This is key in this contract; anyone that bids may become a participant. +- 15 The contract as the new participant for their bid. +- 16 The new bid should be public and it's deposited into the contract. +- 19 The new bid must be bigger than the current one in order to replace it. +- 21 The previous highest bidder gets its money back since it has been replaced by the new bid. +- 22 Now the auction may continue, recursively, with a new highest bidder. +- 23 If the new bidder, reaches the *buy it now* price. Then the auction is settled right now. +- 29 If the expiration time is reached, then the auction is settled. + + +## Lessons learned + +- Recursive function definitions +- How to involve participants that aren't known beforehand. +- How to have an expiration date + + +# How does Crowdfunding.glow work? + +In this day and age, crowdfunding campaigns are known. +Platforms like kickstarter.com and GoFund.me have made the crowdfunding model known in the world +as an excellent way to pull together the resources of several parties that don't know each other +and yet are willing to contribute a little bit of their money towards a goal. + + +## Glow code + + 1 data Action = Pledge(TokenAmount) | Close | Reclaim(TokenAmount); + 2 + 3 let platformCommission amount = quotient(amount, 100); + 4 + 5 @interaction + 6 let crowdfunding = (target: TokenAmount, + 7 expirationTime : Timestamp) => { + 8 require! expirationTime > currentTime(); + 9 + 10 let rec crowdfund = (ledger : Table(TokenAmount <- Participant), + 11 totalPledged: TokenAmount) => { + 12 assert! totalPledged == totalAmount(ledger); + 13 choice { + 14 | ForAllParticipant (NewPledger) { + 15 @NewPledger amount = + 16 input(["Enter next pledge"], TokenAmount); + 17 publish! NewPledger -> Pledge(amount); + 18 deposit! NewPledger -> amount; + 19 require! currentTime() < expirationTime; + 20 crowdfund(Table.add(ledger, NewPledger, amount), + 21 totalPledged + amount); + 22 + 23 | publish! Organizer -> Success; + 24 require! currentTime() >= expirationTime; + 25 require! totalPledged >= target; + 26 let commission = platformCommission(totalPledged); + 27 withdraw! Platform <- commission; + 28 withdraw! Organizer <- totalPledged - commission; + 29 + 30 | ForAllParticipant(Pledger) + 31 publish! Pledger -> Reclaim(amount); + 32 require! currentTime() >= expirationTime; + 33 require! totalPledged < target; + 34 require! Table.get(ledger, Pledger) == amount; + 35 withdraw! Pledger <- amount; //(ref: return_amount_to_pledger) + 36 crowdfund(Table.remove(ledger, Pledger), //(ref: remove_pledger_from_ledger) + 37 totalPledged - amount); + 38 } + 39 crowdfund({}, 0); + 40 } + +- 7 When creating a campaign, there is a goal and an expiration time. + +- 11 We create a `ledger` where we record the `Pledgers` and the total amoun the campaign has raised so far + +Now three things can happen: + +- There is a new Pledge +- Or the campaign was a successor +- A pledger reclaims a refund. + +Let's look at all three in detail. + + +### There is a new Pledge + +Any participant can pledge 14. +The `NewPledger` must `deposit!` her amount to the contract 18. +And the pledge is stored in the `Ledger` 20. + + +### campaign is successful + +23 When the organizer declares the campaign a success. +24 We must make sure the deadline for the campaign has passed and +25 The `totalPledged` surpassed the `target`. + + +### Pledger requests a reimbursement. + +When a pledger requests a reimbursement 30. +We check that the expiration date has passed 32 and +that the goal wasn't achieved 33 . +Then we check that the amount that is reclaiming is the same we have stored in the Ledger 34. +We return the amount to the Pledger and remove it from the Ledger. + + +## Lessons learned + +- Explicit timeout +- Unrestricted open set of participants +- Choice restricted to timeouts and open participation + + +## Challenge + +Could you write a version of this contract that +a) Given the timeout automatically decides if the campaign was successful or not +b) It reimburses all the Pledges automatically. + + +# Challenge: Translate a Solidity smart contract to Glow + +In order to learn something new, we normally try to learn it refers to something we already know. +That's why in this article, we are going to learn the Glow smart contract language +by studying an example in Solidity and then translating it to Glow + + +## The Ballot example + +Ballot.sol is the first program that loads when looking going to the Remix IDE + + pragma solidity >=0.7.0 <0.8.0; + contract Ballot { + +Declare a struct called Voter that is a complex type +consisting of the weight of a vote, a Boolean voted, +the address of the Voter, and an index called vote. + + struct Voter { + uint weight;// Weight is accumulated by delegation + bool voted; // if true, that person already voted + address delegate;// person delegated to + uint vote; // index of the voted proposal + } + +You have an address type called chairperson. + + address chairperson; + +You have a mapping where you map and address with a voter + + mapping(address => Voter) voters; + +You also create an array of proposals where each proposal is a complex type struct. + + Proposal[] proposals; + + struct Proposal { + // If you can limit the length to a certain number of bytes, + // always use one of bytes1 to bytes32 because they are much cheaper + bytes32 name; // short name (up to 32 bytes) + uint voteCount;// number of accumulated votes + } + +In the constructor Ballot, you initialize the chairperson as the message sender with weight 1. +You also create a list of proposals. + + constructor(bytes32[] memory proposalNames) { + chairperson = msg.sender; + voters[chairperson].weight = 1; + + for (uint i = 0; i < proposalNames.length; i++) { + // 'Proposal({...})' creates a temporary + // Proposal object and 'proposals.push(...)' + // appends it to the end of 'proposals'. + proposals.push(Proposal({ + name: proposalNames[i], + voteCount: 0 + })); + } + } + +Give the `Voter` the right to vote on this ballot. +It can only be called by the `Chairperson`. +Validate that the voters have not voted yet and assign voters a weight. + + function giveRightToVote(address voter) public { + require( + msg.sender == chairperson, + "Only chairperson can give right to vote." + ); + require( + !voters[voter].voted, + "The voter already voted." + ); + require(voters[voter].weight == 0, + "the voter already had voting rights"); + voters[voter].weight = 1; + } + +Then the delegate() function delegates your vote to the Voter $(to) after a couple of validations +such as the message sender is not the to address has not voted. + + function delegate(address to) public { + Voter storage sender = voters[msg.sender]; + require(!sender.voted, "You already voted."); + require(to != msg.sender, "Self-delegation is disallowed."); + + while (voters[to].delegate != address(0)) { + to = voters[to].delegate; + + // We found a loop in the Delegation, not allowed. + require(to != msg.sender, "Found loop in delegation."); + } + sender.voted = true; + sender.delegate = to; + Voter storage delegate_ = voters[to]; + if (delegate_.voted) { + // If the delegate already voted, + // directly add to the number of votes + proposals[delegate_.vote].voteCount += sender.weight; + } else { + // If the delegate did not vote yet, + // add to her weight. + delegate_.weight += sender.weight; + } + } + +Give your vote (including votes delegated to you) to proposal + + function vote(uint proposal) public { + Voter storage sender = voters[msg.sender]; + require(sender.weight != 0, "Has no right to vote"); + require(!sender.voted, "Already voted."); + sender.voted = true; + sender.vote = proposal; + + // If 'proposal' is out of the range of the array, + // this will throw automatically and revert all + // changes. + proposals[proposal].voteCount += sender.weight; + } + +Find which is the proposal with the most votes. + + function winningProposal() public view + returns (uint winningProposal_) + { + uint winningVoteCount = 0; + for (uint p = 0; p < proposals.length; p++) { + if (proposals[p].voteCount > winningVoteCount) { + winningVoteCount = proposals[p].voteCount; + winningProposal_ = p; + } + } + } + +Get the name of the winning proposal + + function winnerName() public view + returns (bytes32 winnerName_) + { + winnerName_ = proposals[winningProposal()].name; + } + } + + +## Visualization + +By reading the previous contract, we can identify the following actors and flow. +The `Chairman` creates a contract with a defined number of options. +Then gives names to each option. +And grants voting rights to voters. +A voter (Bob in this diagram) can delegate his vote to another voter. +Voters vote for one of the options by its number. +Then everyone can ask who is winning by the one that has more votes. + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/ballot.png) + + +## How does the same contract look in Glow? + +Now is your turn. How does the previous smart contract look in Glow? + +Here are few ideas on how you could start to think of such a program: + +- One Known Proposal, One known Voter +- Multiple known proposals, One known Voter +- Multiple Known Proposals, Three known voters +- Multiple Known Proposals, Three known voters, With Delegation +- Multiple Known Proposals, unknown voters, With Delegation +- Multiple Known Proposals, unknown voters, With Delegation, with giving voting rights From 0d7ec456c761c9ec1aa1afcae97e423ed38c2e78 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Fri, 19 Feb 2021 15:56:51 +0000 Subject: [PATCH 02/99] Update 2021-02-03_07-00-00_learning-glow-by-example.md some minor tweaks and suggestions --- ...02-03_07-00-00_learning-glow-by-example.md | 108 +++++++++--------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md index d47c4f1af..f37d8b168 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md @@ -1,14 +1,14 @@ --- -title: Learning Glow by Example -description: Study Glow by looking at code examples +title: Learn Glow by Example +description: Study Glow using code examples order: 2 parent: 2020-05-04_06-00-00_glow last_updated: "2021-02-03T07:00:00+01:00" hasNoChildContent: true --- --- -title: Learning Glow by Example -description: Study Glow by looking at code examples +title: Learn Glow by Example +description: Study Glow using code examples order: 1 parent: 2020-05-04_06-00-00_glow last_updated: "2021-02-03T07:00:00+01:00" @@ -16,9 +16,11 @@ hasNoChildContent: true --- -# Learning Glow by Example +# Learn Glow by Example -In 2007, Joel Spolsky was pondering What technology was going to win in the browser development: +We are at a crossroads in smart contract development technology and Glow provides a new portable language where you don't need to know about the low level details of blockchain, but can develop smart contracts easily. + +In 2007, Joel Spolsky was pondering What technology was going to win in browser development: > What's going to happen? > The winners are going to do what worked at Bell Labs in 1978: @@ -30,7 +32,7 @@ In 2007, Joel Spolsky was pondering What technology was going to win in the brow We are probably at the same crossroads in smart contract development technology. As Joel puts it, the "winners" are going to be the ones that create a portable language. -In that regard, Glow is a programming language tailored to the challenges of smart contract development, +Glow is a programming language tailored to the challenges of smart contract development, so that you don't have to worry about the low-level details of the blockchain implementation. It takes ReasonML's syntax (itself a safe subset of javascript), couples it with a powerful compiler that has added support for: @@ -42,36 +44,36 @@ couples it with a powerful compiler that has added support for: To create a language in which describing smart contracts is *easy and safe*. -In this article, we are going to analyze the glow sample programs provided in the distribution to learn -How they work, and how could we apply them to our own needs. +In this article, we are going to analyze the sample Glow programs that are provided in the distribution to learn +how they work, and how could we apply them to our own needs. # Buy Signature ([buysig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? -Let's imagine you want to have your Testament notarized. What would you do? +Let's imagine you want to have your testament notarized. What would you do? -> Probably you will write your Testament, -> And pay a Notary to stamp it, +> Probably you will write your testament, +> And pay a notary to stamp it, > and store a copy for future reference. If we think about it, there are many interactions in the world that follow that same process: - When you have your diploma certified by your university. -- When you renew your Driver's license, there is no test, just a new stamp on it. +- When you renew your driver's license, there is no test, just a new stamp on it. We could generalize the process as: -> A Buyer (you in this case) -> Pays a Seller -> Takes something, or better yet, a representation of the thing, a Digest -> to a Seller. -> So that the Seller Signs the Digest. -> And everyone can see that the Digest was Signed. +> A buyer (you in this case) +> Pays a seller +> Takes something, or better yet, a representation of the thing, a digest +> to a seller. +> So that the seller signs the digest. +> And everyone can see that the digest was signed. -Well this is the interaction that the `buy_sig.glow` contract codifies. +This is the interaction that the `buy_sig.glow` contract codifies. -## Visualizing the Buyer / Seller interactions +## Visualizing the Buyer and Seller interactions ![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/buy_sig.png) @@ -88,19 +90,19 @@ Well this is the interaction that the `buy_sig.glow` contract codifies. 8 withdraw! Seller <- price; 9 } -2. Buyer and Seller have agreed to the terms of this sale. Know what the signature is about, and they want to conduct this sale. -3. The Digest of the message to sign is a parameter of the interaction, as is the convened price. -4. The Buyer deposits the money according to the price. -5. Seller signs. But it's private only to the Seller -6. The signature is made for public for everyone to see. -7. the signature is verified by everyone in a way that the contract enforces. -8. Finally, the money is transferred to the Seller. +2. Buyer and seller have agreed to the terms of this sale. They both know what the signature is about, and they want to conduct this sale. +3. The digest of the message to sign is a parameter of the interaction, as is the convened price. +4. The buyer deposits the money according to the price. +5. The seller signs, but it is private only to the seller. +6. The signature is made public for everyone to see. +7. The signature is verified by everyone in a way that the contract enforces. +8. Finally, the money is transferred to the seller. -There several things to notice: +There are several things to notice: -1. The code looks a lot like the sequence diagram we created before +1. The code looks a lot like the sequence diagram we created before. 2. The lines of code with @Seller annotation are private. -3. The language itself takes care of requirements. If the Buyer never deposits, then the Seller never will be able to sign. +3. The language itself takes care of requirements. If the buyer never deposits, then the seller never will be able to sign. ## Lessons learned @@ -417,10 +419,10 @@ a price to buy it immediately `buyItNowPrice`. # How does Crowdfunding.glow work? -In this day and age, crowdfunding campaigns are known. -Platforms like kickstarter.com and GoFund.me have made the crowdfunding model known in the world +In this day and age, crowdfunding campaigns are well known. +Platforms like kickstarter.com and GoFund.me have made the crowdfunding model well known across the world as an excellent way to pull together the resources of several parties that don't know each other -and yet are willing to contribute a little bit of their money towards a goal. +and yet are willing to contribute some money towards a goal. ## Glow code @@ -472,28 +474,28 @@ and yet are willing to contribute a little bit of their money towards a goal. Now three things can happen: -- There is a new Pledge -- Or the campaign was a successor -- A pledger reclaims a refund. +- There is a new pledge +- The campaign was a successor +- A pledger reclaims a refund Let's look at all three in detail. -### There is a new Pledge +### Dealing with a new pledge Any participant can pledge 14. The `NewPledger` must `deposit!` her amount to the contract 18. And the pledge is stored in the `Ledger` 20. -### campaign is successful +### Campaign is successful 23 When the organizer declares the campaign a success. 24 We must make sure the deadline for the campaign has passed and 25 The `totalPledged` surpassed the `target`. -### Pledger requests a reimbursement. +### Pledger requests a reimbursement When a pledger requests a reimbursement 30. We check that the expiration date has passed 32 and @@ -511,9 +513,9 @@ We return the amount to the Pledger and remove it from the Ledger. ## Challenge -Could you write a version of this contract that -a) Given the timeout automatically decides if the campaign was successful or not -b) It reimburses all the Pledges automatically. +Can you write a version of this contract that does the following: +a) Automatically decides if the campaign was successful or not (given the timeout). +b) Reimburses all the pledges automatically. # Challenge: Translate a Solidity smart contract to Glow @@ -665,7 +667,7 @@ Get the name of the winning proposal ## Visualization -By reading the previous contract, we can identify the following actors and flow. +By reading the previous contract, we can identify the following actors and flow: The `Chairman` creates a contract with a defined number of options. Then gives names to each option. And grants voting rights to voters. @@ -676,15 +678,15 @@ Then everyone can ask who is winning by the one that has more votes. ![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/ballot.png) -## How does the same contract look in Glow? +## How does the contract look in Glow? -Now is your turn. How does the previous smart contract look in Glow? +Now it is your turn. How does the previous smart contract look in Glow? -Here are few ideas on how you could start to think of such a program: +Here are a few ideas on how you could get started with such a program: -- One Known Proposal, One known Voter -- Multiple known proposals, One known Voter -- Multiple Known Proposals, Three known voters -- Multiple Known Proposals, Three known voters, With Delegation -- Multiple Known Proposals, unknown voters, With Delegation -- Multiple Known Proposals, unknown voters, With Delegation, with giving voting rights +- One known proposal, one known voter +- Multiple known proposals, One known voter +- Multiple known proposals, Three known voters +- Multiple known proposals, Three known voters, with delegation +- Multiple known proposals, unknown voters, with delegation +- Multiple known proposals, unknown voters, with delegation, with giving voting rights From 33d255ba111d2ed9dacf06f1ad97a4d6054d51f9 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Mon, 22 Feb 2021 16:41:20 +0000 Subject: [PATCH 03/99] Update 2020-11-25_09-00-00_overview-en.md minor update --- .../content/articles/en/2020-11-25_09-00-00_overview-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md b/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md index 1c11984a0..f8f3268c0 100644 --- a/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md +++ b/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md @@ -14,5 +14,5 @@ Glow is a language to develop not just a smart contract, but an entire DApp itse Additionally, the Glow compiler generates matching client code, and a logical model of your DApp, so you can actually prove that it is correct prior to deploying it. From a single Glow specification, the compiler will generate matching code for both the DApp client and the smart contract itself. The runtime component tracks the code versions to ensure you are always using the correct, matching, and trusted versions of both the client and smart contract. Finally, since correctness is such a priority for DApps, Glow helps you specify a logical model of your DApp, so you can formally verify that it is indeed correct. -We are currently working on additional documentation to support our integration with Glow, and explain exactly how you can use and interact with this language. We’ll be expanding these pages over the weeks and months ahead; [take our short survey](https://input-output.typeform.com/c/OJsf0XcD) to be kept informed of all the latest updates. +Glow is the very latest addition to the suite of developer tools languages for Cardano. Here’s where to get started. We will be expanding the list of resources and documentation to support our integration with Glow over the weeks ahead. If you want to get involved, please join our dedicated devnets developer program by [taking our short survey](https://input-output.typeform.com/c/OJsf0XcD). From 38c25c2cd1fe142f7384670d79c6f385a0e75922 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Tue, 23 Feb 2021 13:13:10 +0000 Subject: [PATCH 04/99] Update 2021-02-03_07-00-00_learning-glow-by-example.md --- .../en/2021-02-03_07-00-00_learning-glow-by-example.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md index f37d8b168..655b433f9 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md @@ -1,5 +1,5 @@ --- -title: Learn Glow by Example +title: Glow Tutorial description: Study Glow using code examples order: 2 parent: 2020-05-04_06-00-00_glow @@ -7,8 +7,8 @@ last_updated: "2021-02-03T07:00:00+01:00" hasNoChildContent: true --- --- -title: Learn Glow by Example -description: Study Glow using code examples +title: Glow Tutorial +description: Learn Glow using code examples order: 1 parent: 2020-05-04_06-00-00_glow last_updated: "2021-02-03T07:00:00+01:00" @@ -16,7 +16,7 @@ hasNoChildContent: true --- -# Learn Glow by Example +# Glow Tutorial We are at a crossroads in smart contract development technology and Glow provides a new portable language where you don't need to know about the low level details of blockchain, but can develop smart contracts easily. From 4ef1382f2df3042d46c9af59dafe68ed0f8298e7 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Tue, 23 Feb 2021 19:41:29 +0000 Subject: [PATCH 05/99] Update 2021-02-03_07-00-00_learning-glow-by-example.md further tweaks and edits --- ...02-03_07-00-00_learning-glow-by-example.md | 139 +++++++----------- 1 file changed, 53 insertions(+), 86 deletions(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md index 655b433f9..36976c73e 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md @@ -18,59 +18,34 @@ hasNoChildContent: true # Glow Tutorial -We are at a crossroads in smart contract development technology and Glow provides a new portable language where you don't need to know about the low level details of blockchain, but can develop smart contracts easily. +Glow is a language for developing secure decentralized apps (DApps) that can run on different blockchains. -In 2007, Joel Spolsky was pondering What technology was going to win in browser development: - -> What's going to happen? -> The winners are going to do what worked at Bell Labs in 1978: -> build a programming language, like C, that's portable and efficient. -> It should compile down to "native" code (native code being JavaScript and DOMs) -> with different backends for different target platforms, -> where the compiler writers obsess about performance so you don't have to. -> – Joel Spolsky: [Strategy Letter VI](https://www.joelonsoftware.com/2007/09/18/strategy-letter-vi/) - -We are probably at the same crossroads in smart contract development technology. -As Joel puts it, the "winners" are going to be the ones that create a portable language. -Glow is a programming language tailored to the challenges of smart contract development, -so that you don't have to worry about the low-level details of the blockchain implementation. -It takes ReasonML's syntax (itself a safe subset of javascript), -couples it with a powerful compiler that has added support for: - -- Game-Theoretic Safety -- Asynchronous communication -- Multi-Party Computation -- Consensual Asset Control - -To create a language in which describing smart contracts is *easy and safe*. - -In this article, we are going to analyze the sample Glow programs that are provided in the distribution to learn -how they work, and how could we apply them to our own needs. +In this tutorial, we analyze the sample programs that are provided in the Glow distribution to learn +how they work, and how could they can be applied to smart contract and DApp development. # Buy Signature ([buysig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? Let's imagine you want to have your testament notarized. What would you do? -> Probably you will write your testament, -> And pay a notary to stamp it, -> and store a copy for future reference. +> You first write your testament +> You pay a notary to stamp it +> You store a copy for future reference -If we think about it, there are many interactions in the world that follow that same process: +If you think about it, there are many interactions in the world that follow that same process: -- When you have your diploma certified by your university. -- When you renew your driver's license, there is no test, just a new stamp on it. +- When your diploma is certified by your University. +- When you renew your driver's license, there is no test, just a renewal stamp. We could generalize the process as: > A buyer (you in this case) > Pays a seller -> Takes something, or better yet, a representation of the thing, a digest -> to a seller. -> So that the seller signs the digest. -> And everyone can see that the digest was signed. +> Takes something, or better yet, a representation of the item (a digest) to a seller. +> The seller can now sign the digest. +> All parties can see that the digest was signed. -This is the interaction that the `buy_sig.glow` contract codifies. +This is the interaction that the `buy_sig.glow` contract represents. ## Visualizing the Buyer and Seller interactions @@ -98,7 +73,7 @@ This is the interaction that the `buy_sig.glow` contract codifies. 7. The signature is verified by everyone in a way that the contract enforces. 8. Finally, the money is transferred to the seller. -There are several things to notice: +There are several things to note: 1. The code looks a lot like the sequence diagram we created before. 2. The lines of code with @Seller annotation are private. @@ -114,15 +89,15 @@ When an instruction is annotated with the participant's name, that value is priv - There are clear instructions for `deposit!` and `withdraw!` -# How can we flip a coin in Glow? (coinflip.glow) +# How can you flip a coin in Glow? (coinflip.glow) Flipping a coin is a game as old as, well, coins. Alice throws the coin *in the air*, -And Bob calls whatever he thinks is going to come out. -And the loser pays the winner. Whatever the amount was. +Bob calls whatever he thinks is going to be the outcome. +The loser pays the winner the agreed amount. -However, in the blockchain, there is no such thing as *in the air*. -So how could we have something random that has a 50 / 50 chance for Alice? +However, on blockchain, there is no such thing as *in the air*. +So, how can we have something random that has a 50 / 50 chance for Alice? For example, Alice flips her coin. Bob flips his coin @@ -138,7 +113,7 @@ Both outcomes have a 50 / 50 chance of happening. ## Glow code -So to represent the previous interaction in Glow. +The following Glow code exmaple represents the previous interaction: 1 #lang glow 2 @interaction([A, B]) @@ -159,25 +134,25 @@ So to represent the previous interaction in Glow. 17 } 18 }; -1. Every glow program starts with the #lang glow identification +1. Every Glow program starts with the #lang glow identification 2. We know that two actors, A and B (Alice and Bob), are going to participate in this contract -3. coinFlip requires to know the amount each player is going to bet to get started. +3. coinFlip needs to know the amount each player is going to bet to get started. 4. Alice needs to be assured that there is a state where she can win. Ie. `assert!` makes sure that the program can reach the label `A_wins` 5. Alice draws random numbers between 0 and 2256. Approx. 78 decimal digits. -6. Alice stores in the commitment value the Digest of the random number she generated. -7. She publishes her commitment in the blockchain and deposits her wager. +6. Alice stores in the commitment value the digest of the random number she generated. +7. She publishes her commitment on the blockchain and deposits her wager. -Now is Bob's turn +Now it is Bob's turn: -8. Bob makes sure that it's possible to get to the `B_wins` label to know that he can win. -9. Bob flips a coin. i.e., Draw a random number between 0 and 2256. -10. Bob publishes the coin that he flipped and deposits his wager +8. Bob makes sure that it is possible to get to the `B_wins` label to know that he can win. +9. Bob flips a coin. i.e., draws a random number between 0 and 2256. +10. Bob publishes the coin that he flipped and deposits his wager. 11. Alice publishes the coin that she threw. 12. We `verify!` that the commitment matches the coin that she threw. 13. By doing a bitwise XOR of the random numbers thrown by Alice and Bob, we find that they match 14. Alice wins and withdraws two times the wager -15. but, If the `xor` doesn't match, Bob wins and -16. Gets double the bet. +15. However, If the `xor` doesn't match, Bob wins +16. In addition, Bob gets double the bet. ## Lessons learned @@ -189,16 +164,16 @@ Now is Bob's turn # Playing Rock, Paper, Scissors (rps-min.glow)? -Rock, Paper, Scissors is the classic children game where both kids show at the same time what they have picked. -And decide who won based on the following rules: +Rock, paper, scissors is the classic children's game where each child shows what they have chosen at the same time. +The decision on who has won is based on the following rules: - Both selected the same: Draw -- Rock beats Scissors -- Paper beats Rock -- Scissors beats Paper +- Rock beats scissors +- Paper beats rock +- Scissors beats paper -But how con we codify this in Glow if there is not at the *same time*. -And How a player communicates its pick to the blockchain during the game? +How con you code this in Glow if there is no *at the same time*. +How does a player communicate their choice to the blockchain during the game? ## Visualization @@ -235,8 +210,8 @@ And How a player communicates its pick to the blockchain during the game? 25 | Draw => withdraw! A <- wagerAmount; withdraw! B <- wagerAmount }} 2. A `Hand` can only be `Rock, Paper or Scissors` -3. There are only three possible `Outcome` either `B_wins`, `A_wins` or its a `Draw` -4. Now define a function `winner`, that given two hands can determine the `Outcome` +3. There are only three possible `Outcome` either `B_wins`, `A_wins`, or its a `Draw` +4. Now define a function `winner`, that when given two hands can determine the `Outcome` 5. This is an arithmetic trick that translates each of the nine possible hand combinations to three possible outcomes 6. @@ -272,21 +247,13 @@ And How a player communicates its pick to the blockchain during the game? # How to create a deadman switch works? -Let's suppose a millionaire uncle is about to die, -and he has called for you because he will give you the password to all his fortune. -However, while you are traveling to see your dear uncle; -He passes away, and only he knew the password for the safe! - -Heartbroken because of the loss of your uncle, you return to a boring job. +Let's suppose a millionaire unlce has called you because he will give you the password to all his fortune. +However, while you are traveling to see your relative he passes away, and only he knew the password for the safe! -However, six months later, you get an email with the password for the safe! -It turns out your uncle had a *dead man switch* that would automatically reveal the password. - -You knew it! Your uncle always was super smart. +Six months later, you get an email with the password for the safe and it turns out that your uncle had a *dead man switch* that would automatically reveal the password. In this contract, we are going to see how your uncle implemented that contract in Glow. - ## Visualization ![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png) @@ -327,8 +294,8 @@ In this contract, we are going to see how your uncle implemented that contract i - 15 It renews the *dead man switch* with a new deadline. - 16 When the `@heir` signals on the blockchain that is ready to inherit. -The contract checks if the current block is over the expiration day. -If it is, releases the funds to the `heir`. +The contract checks if the current block is past the expiration day. +If this is the case, the funds are released to the `heir`. ## Lessons learned @@ -339,9 +306,9 @@ If it is, releases the funds to the `heir`. # How does the Simple Auction (auction.glow) contract work? -Imagine an auction like in the movies where each one of the bidders tries to outbid the previous one. -However, in a blockchain auction, each bidder has to put the money first in order to get to be the top bidder. -And then they get their money back when they are outbid. +Imagine an auction where each one of the bidders tries to outbid the previous bidder. +However, in a blockchain auction, each bidder has to declare the money first to become the top bidder. +They get their money back when they are outbid. ## Visualization @@ -391,9 +358,9 @@ And then they get their money back when they are outbid. - 4 Only the Seller can create an auction - **5:** In order to create an auction, a Seller must provide: -the `Goods` that could be anything that can be codified as an asset, +The `Goods` that could be anything that can be represented as an asset, an `expirationTime` at which point the auction is over and -a price to buy it immediately `buyItNowPrice`. +a price at which to buy it immediately `buyItNowPrice`. - 8 The Seller must deposit the goods in the smart contract. This could, for example, a photograph. - 34 The real auction begins at 0, and the "first bidder" is the Seller himself. @@ -413,16 +380,16 @@ a price to buy it immediately `buyItNowPrice`. ## Lessons learned - Recursive function definitions -- How to involve participants that aren't known beforehand. -- How to have an expiration date +- How to involve participants that are not known beforehand. +- How to use an expiration date # How does Crowdfunding.glow work? In this day and age, crowdfunding campaigns are well known. Platforms like kickstarter.com and GoFund.me have made the crowdfunding model well known across the world -as an excellent way to pull together the resources of several parties that don't know each other -and yet are willing to contribute some money towards a goal. +as an excellent way to bring together the resources of several parties that do not know each other +and yet are willing to contribute some money towards a common goal. ## Glow code From 794cf9cde522d723b5c4ac4651dc4c397490c20c Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:34:47 +0000 Subject: [PATCH 06/99] Create 2021-02-25_11-00-00_evm-en.md --- .../content/articles/en/2021-02-25_11-00-00_evm-en.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_evm-en.md diff --git a/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md new file mode 100644 index 000000000..475d3328f --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md @@ -0,0 +1,7 @@ +--- +title: EVM +description: KEVM section +parent: 2020-05-04_07-00-00_virtual-machines +order: 2 +last_updated: "2021-02-25T09:00:00+01:00" +--- From 77faf2d0f629894fb9266432bc4fea4a70b4265c Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:35:42 +0000 Subject: [PATCH 07/99] Update 2020-05-04_10-00-00_iele-en.md --- resources/content/articles/en/2020-05-04_10-00-00_iele-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2020-05-04_10-00-00_iele-en.md b/resources/content/articles/en/2020-05-04_10-00-00_iele-en.md index 63d92eb62..73875a276 100644 --- a/resources/content/articles/en/2020-05-04_10-00-00_iele-en.md +++ b/resources/content/articles/en/2020-05-04_10-00-00_iele-en.md @@ -2,6 +2,6 @@ title: IELE description: IELE section parent: 2020-05-04_07-00-00_virtual-machines -order: 3 +order: 4 last_updated: "2020-05-01T09:00:00+01:00" --- From fe0c734047e4b33481ca1efaeb3cc77a569fb3b7 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:36:07 +0000 Subject: [PATCH 08/99] Update 2021-02-25_11-00-00_evm-en.md --- resources/content/articles/en/2021-02-25_11-00-00_evm-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md index 475d3328f..6afc3c63d 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md +++ b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md @@ -2,6 +2,6 @@ title: EVM description: KEVM section parent: 2020-05-04_07-00-00_virtual-machines -order: 2 +order: 3 last_updated: "2021-02-25T09:00:00+01:00" --- From a9ce264970ca125d37c87cd5d1af9730404e5563 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:47:25 +0000 Subject: [PATCH 09/99] Create 2021-02-25_11-00-00_overview-en --- .../articles/en/2021-02-25_11-00-00_overview-en | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_overview-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_overview-en b/resources/content/articles/en/2021-02-25_11-00-00_overview-en new file mode 100644 index 000000000..2734b95ec --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_overview-en @@ -0,0 +1,15 @@ +--- +title: Overview +description: KEVM overview +parent: 2021-02-25_11-00-00_evm-en +order: 1 +last_updated: "2021-02-25T11:30:00+01:00" +hasNoChildContent: true + +--- +## Overview +The Ethereum Virtual Machine (EVM) is a sandboxed virtual software stack, designed to enable the execution of smart contracts across a decentralized network of computers. It is embedded within every full Ethereum node, where every node on the network runs an instance, and thus reaches consensus. + +The EVM provides a runtime environment for smart contracts in Ethereum. Contracts will typically be written in a higher-level programming language, like Solidity, or in a DSL like [Glow](https://glow-lang.org/), and then compiled to low level EVM bytecode. + +By providing EVM support throughout our devnets programme, developers can write DApps in Solidity – Ethereum’s most popular smart contract language or Glow, as well as other EVM languages, and in time deploy these contracts on Cardano via sidechains. From 910ec15caf08cdb9d60d5dfe7cc34949f21c4901 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:48:08 +0000 Subject: [PATCH 10/99] Rename 2021-02-25_11-00-00_evm-en.md to 2021-02-25_11-00-00_evm-en --- .../{2021-02-25_11-00-00_evm-en.md => 2021-02-25_11-00-00_evm-en} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_evm-en.md => 2021-02-25_11-00-00_evm-en} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md b/resources/content/articles/en/2021-02-25_11-00-00_evm-en similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_evm-en.md rename to resources/content/articles/en/2021-02-25_11-00-00_evm-en From 33f1e4cb874ee1086672389dc92aca5c6a06e585 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:54:27 +0000 Subject: [PATCH 11/99] Create 2021-02-25_11-00-00_about-en.md --- .../content/articles/en/2021-02-25_11-00-00_about-en.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_about-en.md diff --git a/resources/content/articles/en/2021-02-25_11-00-00_about-en.md b/resources/content/articles/en/2021-02-25_11-00-00_about-en.md new file mode 100644 index 000000000..fe5eb8caa --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_about-en.md @@ -0,0 +1,7 @@ +--- +title: About +description: EVM +parent: 2021-02-25_11-00-00_evm +order: 2 +last_updated: "2021-02-25T09:00:00+01:00" +--- From 62a448f7c9cdf07dacd336b183befd9bf2a45b90 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:55:46 +0000 Subject: [PATCH 12/99] Rename 2021-02-25_11-00-00_about-en.md to 2021-02-25_11-00-00_about-en --- ...21-02-25_11-00-00_about-en.md => 2021-02-25_11-00-00_about-en} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_about-en.md => 2021-02-25_11-00-00_about-en} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_about-en.md b/resources/content/articles/en/2021-02-25_11-00-00_about-en similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_about-en.md rename to resources/content/articles/en/2021-02-25_11-00-00_about-en From 6481c7b22111a72414a48dd708b61efb99ca0683 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:57:27 +0000 Subject: [PATCH 13/99] Create 2021-02-25_11-00-00_devnet-skill-set-en --- .../en/2021-02-25_11-00-00_devnet-skill-set-en | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en b/resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en new file mode 100644 index 000000000..e620d6eb1 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en @@ -0,0 +1,16 @@ +--- +title: Devnet skill set +description: EVM about +parent: 2021-02-25_11-00-00_about +order: 1 +last_updated: "2021-02-25T09:00:00+01:00" + +--- +## Devnet skill set + +As in the case of the KEVM to use the EVM devnet the following skills are required: + +- Familiarity with writing smart contracts in Solidity. You will need a suite of well-defined smart contracts to use on the devnet. +- Knowledge of the JSON remote procedure call (RPC) protocol. + +No registration is required to use the devnet. From b8ad189d631bf9b3b463bf30884abd7efbdb1a91 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:12:26 +0000 Subject: [PATCH 14/99] Create 2021-02-25_00-00-00_smart_contracts_architecture-en --- ...021-02-25_00-00-00_smart_contracts_architecture-en | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en diff --git a/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en new file mode 100644 index 000000000..fa4acdfd0 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en @@ -0,0 +1,11 @@ +--- +title: Smart Contracts Architecture +description: EVM Smart Contracts Architecture +parent: 2021-02-25_11-00-00_about +order: 2 +last_updated: "2021-02-25T09:00:00+01:00" +--- + +## Smart Contracts Architecture + +The smart contract architecture is the same for the KEVM and EVM; see [smart contracts architecture](/en/virtual-machines/kevm/about/iele_vm_architecture/) for more details. From 66af04782eea29bf4b0ea13107d1df1ee15b2d0e Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:15:23 +0000 Subject: [PATCH 15/99] Create 2021-02-25_11-00-00_getting-started-en --- .../articles/en/2021-02-25_11-00-00_getting-started-en | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_getting-started-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en b/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en new file mode 100644 index 000000000..da9dea586 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en @@ -0,0 +1,7 @@ +--- +title: Getting Started +description: EVM +parent: 2021-02-25_11-00-00_evm +order: 3 +last_updated: "2021-02-25T09:00:00+01:00" +--- From eb184bd2a2590685a8c540fdd520727e6876121e Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:20:51 +0000 Subject: [PATCH 16/99] Create 2021-02-25_11-00-00_using-the-evm-devnet-en --- .../en/2021-02-25_11-00-00_using-the-evm-devnet-en | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en b/resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en new file mode 100644 index 000000000..2b0d31536 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en @@ -0,0 +1,11 @@ +--- +title: Using the EVM devnet +description: EVM getting started +parent: 2021-02-25_11-00-00_getting-started +order: 1 +last_updated: "2021-02-25T09:00:00+01:00" + +--- +## Using the EVM devnet + +To get up and running, you need to install Mallet and start compiling your smart contracts. Then you can start experimenting and identify any issues with your smart contracts. From 7f7fe16261ab28f497cdf9766c3511a7f89fa3f1 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:31:04 +0000 Subject: [PATCH 17/99] Create 2021-02-25_11-00-00_mallet-end-to-end-en --- .../2021-02-25_11-00-00_mallet-end-to-end-en | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en b/resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en new file mode 100644 index 000000000..94b2bc877 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en @@ -0,0 +1,270 @@ +--- +title: Mallet end to end tutorial +description: EVM getting started +parent: 2021-02-25_11-00-00_getting-started +order: 5 +last_updated: "2021-02-25T09:00:00+01:00" + +--- + + +## Installation prerequisites + +- Linux and MacOS: Node.js 10.16.3 (recommended), Python (2.7), Curl, Make and Git. +- Windows: Install the same as above within the Windows Subsystem for Linux (WSL). + +Consult the official [nodejs](https://github.com/nodesource/distributions/blob/master/README.md) documentation for reference. + + +### Installing Node.js for Linux and MacOS + +Follow these steps to install Node.js in Linux and MacOS operating systems. + +**1. Open a terminal and execute:** + + curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash - + sudo apt-get -q install -y nodejs + + +**2. Verify Node.js is installed with:** + + node --version + + +**3. Install `nvm` (a version manager for node.js):** + + curl -s -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash + + +**4. Make the `nvm` command available in the current session:** + + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm + + +**5. Verify that `nvm` is installed:** + + nvm --version + + 0.37.2 + +Note: Install Mallet only *after* verifying that `nvm` is installed *and* working. + + +### Installing Mallet 2.0 + +**1. Clone this [repo]() to get the latest version of Mallet, and then +install it with the `npm` command.** + + +**2. Clone the Mallet git repository** + +Open a terminal window and type: + + git clone https://github.com/input-output-hk/mallet + + +**3. Install specific node version for Mallet** + +After cloning the repository, execute: + + cd mallet + + cat .nvmrc + + 10.16.3 + +Then install the required node version: + + nvm install 10.16.3 + nvm use --silent + + +**4. Download and install Mallet and its dependencies:** + + npm install --silent + + +**5. Verify that Mallet was installed correctly** + +Check the integrity of the Mallet installation by using the `version` command: + + ./mallet --version + + 2.1.0 + +If the version number displays correctly, the installation was successful. + +## Create a HelloWorld smart contract + +To deploy your smart contracts on the EVM devnet and test Mallet, +you will need to compile the Solidity code to EVM bytecode. +You can compile the bytecode directly with using [solc](https://hub.docker.com/r/ethereum/solc). + +**1. Create a Solidity file** + +Create a `myContract.sol` file: + + cat << EOF >myContract.sol + // SPDX-License-Identifier: MIT + pragma solidity >=0.5.1 <0.9.0; + + + contract HelloWorld { + function helloWorld() external pure returns (string memory) { + return "Hello, World!"; + } + } + EOF + +**2. Compile with `solc`:** + +To compile with `solc`, you will need to use the Docker command. For this, first install the [Docker Engine](https://docs.docker.com/engine/install/), then run: + + docker run --rm -v $(pwd):/sources ethereum/solc:0.5.1 -o /sources --bin --abi /sources/myContract.sol + +**3. Verify that the compiled file exists:** + +If the file was correctly compiled, there should be a `.bin` file in your directory. + + ls *.bin + + HelloWorld.bin + +## Mallet 2.0 + +Mallet, the minimal wallet, is the command line interface (CLI) used to send +transactions, deploy smart contracts, and interact with the IELE and +EVM devnets. + +**1. Connect to the EVM devnet:** + + ./mallet evm -d ./data + + Mallet 2.1.0 - IELE/EVM devnet utility + Type 'help()' to view the online documentation or 'listCommands()' to view available commands + +This will open a session in the read-eval-print-loop (Repl) environment +for Node.js. Mallet commands are imported automatically. + +Everything typed in the Repl has to be valid JavaScript. Technically +speaking, the commands are simply functions and properties of Mallet +object. However, we tend to refer to them as *commands* because that +reflects how they are used. + +> Note: If you have problems installing any of the prerequisites (node or Mallet), +contact the community in Slack: +[Join IOHK | Devnets on Slack](https://join.slack.com/t/iohkdevnets/shared_invite/zt-jvy74l5h-Bhp5SQajefwjig72BIl73A) + +## Using the faucet + +**1. Create an account** + +Create an account to use this faucet by using this code: + + //execute inthe Mallet Repl + //mallet evm -d ./my_data/ + //mallet> .load ../test_smartcontract_deploy.js + + myAccount = newAccount() + +The `newAccount` command asks your password, and returns your new account +address. + +Note that we are assigning the return value of `newAccount` to a variable +named `myAccount` so we can refer to it later. + + +**2. Select an account** + +Activate the account we have just created by using this code: + + selectAccount(myAccount) + + '0x45402404f51909b640d03f361c742c38d34bb3e7' + + +**3. Verify the balance of your new account** + +Since the account has just been created, its balance should be 0. + + getBalance() + +If you don't give any argument, this will return the balance of the +selected account. + + +**4. Request tokens from the faucet with `requestFunds`:** + + requestFunds() + +Fund transfer might take a few minutes. + +You can now compile and deploy smart contracts as your account is created *and* funded. + + +**5. Check the new balance in the account:** + + getBalance() + + +**6. Bring the compiled smart contract into Mallet** + +Using the `HelloWorld.bin` created earlier you can import the smart contract into Mallet. + + +**7. Import the `fileSystem` module:** + + fs = require("fs"); + + +**8. Read the contents of the binary file:** + + myContract = "0x" + fs.readFileSync('HelloWorld.bin', 'utf8'); + + +## Deploying smart contracts + +Now that you have the bytecode from `solc`, the next step is simply to deploy it. + + +**1. Prepare the transaction to deploy the contract:** + + tx = { gas: 470000, data: myContract} + + +**2. Send a transaction with the smart contract:** + + deploymentHash = sendTransaction(tx) + +This will return the tx hash on which the contract was deployed to. + + +**3. View receipt** + +You can view transaction details with the following command: + + getReceipt(deploymentHash) + + +**4. Save your contract address** + +To save your contract address, create a variable that takes the return value of getReceipt(): + + myContractAddress = getReceipt(deploymentHash).contractAddress + + +### Test your smart contract + + web3.toAscii(web3.eth.call({to: myContractAddress, data: '0xc605f76c'})) + +The expected output should contain "Hello, World!". + + +**Getting help** + +The `help` command can be useful When running Mallet in the CLI. This command opens the **Readme file** in your default web browser: + + help() + +Alternatively, [Join IOHK | Devnets on Slack](https://join.slack.com/t/iohkdevnets/shared_invite/zt-jvy74l5h-Bhp5SQajefwjig72BIl73A) to obtain help from the community. From afa4f1d5fb134ace5857fa730728c3ed3cd7b71e Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:37:04 +0000 Subject: [PATCH 18/99] Create 2021-02-25_11-00-00_block-explorer-en --- .../articles/en/2021-02-25_11-00-00_block-explorer-en | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en b/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en new file mode 100644 index 000000000..558c9a5e5 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en @@ -0,0 +1,11 @@ +--- +title: Block explorer +description: EVM getting started +parent: 2021-02-25_11-00-00_getting-started-en +order: 6 +last_updated: "2020-12-17T09:00:00+01:00" + +--- +## Block explorer + +The EVM devnet provides a link to the blockchain explorer. This is a useful tool that displays information about activity on the blockchain. The block explorer shows transaction history and other details, making it easy for users to find information about the cryptocurrency. Importantly, it shows the latest blocks in the chain as well as identifying the first block in the chain. From 40c94c19cc9c21037feedd9ac6d2fa40c15d9ed3 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:38:56 +0000 Subject: [PATCH 19/99] Create 2021-02-25_11-00-00_resources-en --- .../content/articles/en/2021-02-25_11-00-00_resources-en | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_resources-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_resources-en b/resources/content/articles/en/2021-02-25_11-00-00_resources-en new file mode 100644 index 000000000..139123d76 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_resources-en @@ -0,0 +1,7 @@ +--- +title: Resources +description: EVM +parent: 2021-02-25_11-00-00_evm +order: 4 +last_updated: "2021-02-25T09:00:00+01:00" +--- From 01c392784ea47778670e7f43502a72c0797da2c9 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:43:54 +0000 Subject: [PATCH 20/99] Create 2021-02-25_11-00-00_rpc-endpoints --- .../en/2021-02-25_11-00-00_rpc-endpoints | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints diff --git a/resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints b/resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints new file mode 100644 index 000000000..f93113def --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints @@ -0,0 +1,37 @@ +--- +title: RPC Endpoints +description: RPC endpoints for KEVM +order: 0 +parent: 2021-02-25_11-00-00_resources +last_updated: "2020-12-22T09:00:00+01:00" +--- +## RPC Endpoints + +The following is a list of API calls that are supported. + +```json +eth_accounts +eth_blockNumber +eth_call +eth_estimateGas +eth_gasPrice +eth_getBalance +eth_getblockByHash +eth_getBlockByNumber +eth_getBlockTransactionCountByHash +eth_getBlockTransactionCountByNumber +eth_getTransactionReceipt +eth_getCode +eth_getLogs +eth_getStorageAt +eth_getTransactionByHash +eth_getTransactionCount +eth_getUncleCountByBlockHash +eth_getUncleCountByNumber +eth_getWork +eth_mining +eth_protocolVersion +eth_syncing +``` + +This list is not exclusive and additional calls or further changes may be made to extend this list. From 7afdf2edd1b9a9aeed578980a341ac1b7c048cee Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:55:34 +0000 Subject: [PATCH 21/99] Create 2021-02-25_09-00-00_support-and-help-en --- .../en/2021-02-25_09-00-00_support-and-help-en | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en diff --git a/resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en b/resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en new file mode 100644 index 000000000..31502824e --- /dev/null +++ b/resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en @@ -0,0 +1,13 @@ +--- +title: Support and help +description: EVM resources +order: 2 +parent: 2021-02-25_11-00-00_resources +last_updated: "2021-02-25T09:00:00+01:00" + +--- +## Support and help + +Thank you for your interest in using EVM. If you are a developer and want to get involved, register your interest today via our short [Typeform](https://input-output.typeform.com/to/OJsf0XcD) survey and we will be in touch soon. Invites will be sent out in stages as we roll out the program. + +We encourage you to draw on community feedback and support as much as possible. From 6e7ed9f9aaadde0e8c50b65ff6a9d5e0715fdd5e Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 17:56:59 +0000 Subject: [PATCH 22/99] Create 2021-02-25_11-00-tools-en --- resources/content/articles/en/2021-02-25_11-00-tools-en | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-tools-en diff --git a/resources/content/articles/en/2021-02-25_11-00-tools-en b/resources/content/articles/en/2021-02-25_11-00-tools-en new file mode 100644 index 000000000..8a8d4097a --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-tools-en @@ -0,0 +1,7 @@ +--- +title: Tools +description: EVM +parent: 2021-02-25_11-00-00_evm +order: 5 +last_updated: "2021-02-25T09:00:00+01:00" +--- From 0868d4285707125a084ac1eab9c3a0160f6ccc90 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:01:50 +0000 Subject: [PATCH 23/99] Create 2021-02-25_11-00-00_explorer-en --- .../content/articles/en/2021-02-25_11-00-00_explorer-en | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_11-00-00_explorer-en diff --git a/resources/content/articles/en/2021-02-25_11-00-00_explorer-en b/resources/content/articles/en/2021-02-25_11-00-00_explorer-en new file mode 100644 index 000000000..197a6eec2 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_11-00-00_explorer-en @@ -0,0 +1,8 @@ +--- +title: Explorer +description: EVM tools +parent: 2021-02-25_11-00-tools-en +order: 2 +last_updated: "2020-12-17T09:00:00+01:00" +external_href: https://david.kevm.dev-mantis.iohkdev.io/ +--- From f0b606fc4b49e177524ec8824288fbda3d7eb521 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:03:28 +0000 Subject: [PATCH 24/99] Update and rename 2020-12-14_16-00-00_FAQ_kevm_iele-en.md to 2020-12-14_16-00-00_FAQ_virtual-machines-en.md --- ....md => 2020-12-14_16-00-00_FAQ_virtual-machines-en.md} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename resources/content/articles/en/{2020-12-14_16-00-00_FAQ_kevm_iele-en.md => 2020-12-14_16-00-00_FAQ_virtual-machines-en.md} (98%) diff --git a/resources/content/articles/en/2020-12-14_16-00-00_FAQ_kevm_iele-en.md b/resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md similarity index 98% rename from resources/content/articles/en/2020-12-14_16-00-00_FAQ_kevm_iele-en.md rename to resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md index 3c4564d7e..6741010a4 100644 --- a/resources/content/articles/en/2020-12-14_16-00-00_FAQ_kevm_iele-en.md +++ b/resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md @@ -1,10 +1,10 @@ --- -title: FAQs for KEVM and IELE -description: Frequently asked questions on KEVM -order: 4 +title: FAQs for Virtual Machines +description: Frequently asked questions on Virtual Machines +order: 5 external_href: "" parent: "2020-05-04_07-00-00_virtual-machines" -last_updated: "2020-12-15T11:30:00+01:00" +last_updated: "2021-02-25T11:30:00+01:00" --- ## FAQs for KEVM and IELE From 5e8a1b5b66a9f371365bc40e4b7865ad5ea897d3 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:10:21 +0000 Subject: [PATCH 25/99] Update 2021-02-25_11-00-00_overview-en --- resources/content/articles/en/2021-02-25_11-00-00_overview-en | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_overview-en b/resources/content/articles/en/2021-02-25_11-00-00_overview-en index 2734b95ec..a363e844c 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_overview-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_overview-en @@ -1,6 +1,6 @@ --- title: Overview -description: KEVM overview +description: EVM overview parent: 2021-02-25_11-00-00_evm-en order: 1 last_updated: "2021-02-25T11:30:00+01:00" From 648766363b640358c1409a6d7f147f63265dcbad Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:11:03 +0000 Subject: [PATCH 26/99] Update 2021-02-25_11-00-00_getting-started-en --- .../content/articles/en/2021-02-25_11-00-00_getting-started-en | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en b/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en index da9dea586..a41a31e74 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en @@ -1,7 +1,7 @@ --- title: Getting Started description: EVM -parent: 2021-02-25_11-00-00_evm +parent: 2021-02-25_11-00-00_evm-en order: 3 last_updated: "2021-02-25T09:00:00+01:00" --- From d38793bf53fda81bded1155ab1ae9d4c70887786 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:11:27 +0000 Subject: [PATCH 27/99] Update 2021-02-25_11-00-00_resources-en --- resources/content/articles/en/2021-02-25_11-00-00_resources-en | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_resources-en b/resources/content/articles/en/2021-02-25_11-00-00_resources-en index 139123d76..48867addc 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_resources-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_resources-en @@ -1,7 +1,7 @@ --- title: Resources description: EVM -parent: 2021-02-25_11-00-00_evm +parent: 2021-02-25_11-00-00_evm-en order: 4 last_updated: "2021-02-25T09:00:00+01:00" --- From 1de890d4cf3c701fd6c05aea12dd71412221175c Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:11:57 +0000 Subject: [PATCH 28/99] Update 2021-02-25_11-00-tools-en --- resources/content/articles/en/2021-02-25_11-00-tools-en | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-tools-en b/resources/content/articles/en/2021-02-25_11-00-tools-en index 8a8d4097a..feca45bc4 100644 --- a/resources/content/articles/en/2021-02-25_11-00-tools-en +++ b/resources/content/articles/en/2021-02-25_11-00-tools-en @@ -1,7 +1,7 @@ --- title: Tools description: EVM -parent: 2021-02-25_11-00-00_evm +parent: 2021-02-25_11-00-00_evm-en order: 5 last_updated: "2021-02-25T09:00:00+01:00" --- From c5c1a70ce70f05e43e745be047968a095e75f3af Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:13:25 +0000 Subject: [PATCH 29/99] Update 2021-02-25_11-00-00_about-en --- resources/content/articles/en/2021-02-25_11-00-00_about-en | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_about-en b/resources/content/articles/en/2021-02-25_11-00-00_about-en index fe5eb8caa..3cf2ef1ad 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_about-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_about-en @@ -1,7 +1,7 @@ --- title: About description: EVM -parent: 2021-02-25_11-00-00_evm +parent: 2021-02-25_11-00-00_evm-en order: 2 last_updated: "2021-02-25T09:00:00+01:00" --- From 9324fd767cd50c7bb149fe9ccc985d4b5192034f Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:17:47 +0000 Subject: [PATCH 30/99] Update 2021-02-25_00-00-00_smart_contracts_architecture-en --- .../en/2021-02-25_00-00-00_smart_contracts_architecture-en | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en index fa4acdfd0..e6a38f4ac 100644 --- a/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en +++ b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en @@ -1,7 +1,7 @@ --- title: Smart Contracts Architecture description: EVM Smart Contracts Architecture -parent: 2021-02-25_11-00-00_about +parent: 2021-02-25_11-00-00_about-en order: 2 last_updated: "2021-02-25T09:00:00+01:00" --- From e51103b75280a2aa44a2870762ff8cdc2cfc2a55 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:19:30 +0000 Subject: [PATCH 31/99] Update and rename 2021-02-25_00-00-00_smart_contracts_architecture-en to 2021-02-25_00-00-00_smart_contracts_architecture --- ...ture-en => 2021-02-25_00-00-00_smart_contracts_architecture} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_00-00-00_smart_contracts_architecture-en => 2021-02-25_00-00-00_smart_contracts_architecture} (90%) diff --git a/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture similarity index 90% rename from resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en rename to resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture index e6a38f4ac..fa4acdfd0 100644 --- a/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture-en +++ b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture @@ -1,7 +1,7 @@ --- title: Smart Contracts Architecture description: EVM Smart Contracts Architecture -parent: 2021-02-25_11-00-00_about-en +parent: 2021-02-25_11-00-00_about order: 2 last_updated: "2021-02-25T09:00:00+01:00" --- From f262a1ac5bfea1fd9e7eb6d1c49c5384016233b1 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:20:44 +0000 Subject: [PATCH 32/99] Rename 2021-02-25_11-00-00_evm-en to 2021-02-25_11-00-00_evm-en.md --- .../{2021-02-25_11-00-00_evm-en => 2021-02-25_11-00-00_evm-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_evm-en => 2021-02-25_11-00-00_evm-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_evm-en b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_evm-en rename to resources/content/articles/en/2021-02-25_11-00-00_evm-en.md From f94ce5f2e8257d825861026b37eb4dd012a4e813 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:22:33 +0000 Subject: [PATCH 33/99] Update 2021-02-25_11-00-00_evm-en.md --- resources/content/articles/en/2021-02-25_11-00-00_evm-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md index 6afc3c63d..39d4db20f 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md +++ b/resources/content/articles/en/2021-02-25_11-00-00_evm-en.md @@ -1,6 +1,6 @@ --- title: EVM -description: KEVM section +description: EVM section parent: 2020-05-04_07-00-00_virtual-machines order: 3 last_updated: "2021-02-25T09:00:00+01:00" From e4e953658fd108ac063e69bb7d1fc90d4f16b1b3 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:31:00 +0000 Subject: [PATCH 34/99] Update and rename 2021-02-25_11-00-tools-en to 2021-02-25_11-00-tools-en.md --- .../{2021-02-25_11-00-tools-en => 2021-02-25_11-00-tools-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_11-00-tools-en => 2021-02-25_11-00-tools-en.md} (71%) diff --git a/resources/content/articles/en/2021-02-25_11-00-tools-en b/resources/content/articles/en/2021-02-25_11-00-tools-en.md similarity index 71% rename from resources/content/articles/en/2021-02-25_11-00-tools-en rename to resources/content/articles/en/2021-02-25_11-00-tools-en.md index feca45bc4..8a8d4097a 100644 --- a/resources/content/articles/en/2021-02-25_11-00-tools-en +++ b/resources/content/articles/en/2021-02-25_11-00-tools-en.md @@ -1,7 +1,7 @@ --- title: Tools description: EVM -parent: 2021-02-25_11-00-00_evm-en +parent: 2021-02-25_11-00-00_evm order: 5 last_updated: "2021-02-25T09:00:00+01:00" --- From da1b0061f0efecc38c777f150bbd18683960dc13 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:31:31 +0000 Subject: [PATCH 35/99] Update and rename 2021-02-25_11-00-00_explorer-en to 2021-02-25_11-00-00_explorer-en.md --- ..._11-00-00_explorer-en => 2021-02-25_11-00-00_explorer-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_11-00-00_explorer-en => 2021-02-25_11-00-00_explorer-en.md} (82%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_explorer-en b/resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md similarity index 82% rename from resources/content/articles/en/2021-02-25_11-00-00_explorer-en rename to resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md index 197a6eec2..51b8e5cc2 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_explorer-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md @@ -1,7 +1,7 @@ --- title: Explorer description: EVM tools -parent: 2021-02-25_11-00-tools-en +parent: 2021-02-25_11-00-tools order: 2 last_updated: "2020-12-17T09:00:00+01:00" external_href: https://david.kevm.dev-mantis.iohkdev.io/ From 2223b7c0a1c143b396de6ac89e471b1fe4f78476 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:40:04 +0000 Subject: [PATCH 36/99] Update and rename 2021-02-25_11-00-00_overview-en to 2021-02-25_11-00-00_overview-en.md --- ..._11-00-00_overview-en => 2021-02-25_11-00-00_overview-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_11-00-00_overview-en => 2021-02-25_11-00-00_overview-en.md} (96%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_overview-en b/resources/content/articles/en/2021-02-25_11-00-00_overview-en.md similarity index 96% rename from resources/content/articles/en/2021-02-25_11-00-00_overview-en rename to resources/content/articles/en/2021-02-25_11-00-00_overview-en.md index a363e844c..23b71ba80 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_overview-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_overview-en.md @@ -1,7 +1,7 @@ --- title: Overview description: EVM overview -parent: 2021-02-25_11-00-00_evm-en +parent: 2021-02-25_11-00-00_evm order: 1 last_updated: "2021-02-25T11:30:00+01:00" hasNoChildContent: true From f0ac963d15c2b5ac144f3811529f164a0133d61c Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:45:05 +0000 Subject: [PATCH 37/99] Rename 2021-02-25_11-00-00_using-the-evm-devnet-en to 2021-02-25_11-00-00_using-the-evm-devnet-en.md --- ...m-devnet-en => 2021-02-25_11-00-00_using-the-evm-devnet-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_using-the-evm-devnet-en => 2021-02-25_11-00-00_using-the-evm-devnet-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en b/resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en.md similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en rename to resources/content/articles/en/2021-02-25_11-00-00_using-the-evm-devnet-en.md From 4e5ee396b9f4912fb1b7be9f40c5f83e31d07a32 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:45:27 +0000 Subject: [PATCH 38/99] Rename 2021-02-25_11-00-00_rpc-endpoints to 2021-02-25_11-00-00_rpc-endpoints.md --- ...1-00-00_rpc-endpoints => 2021-02-25_11-00-00_rpc-endpoints.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_rpc-endpoints => 2021-02-25_11-00-00_rpc-endpoints.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints b/resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints.md similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints rename to resources/content/articles/en/2021-02-25_11-00-00_rpc-endpoints.md From 8237a2ce92eff9f736d2c029e17f00015e7bb2e4 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:45:48 +0000 Subject: [PATCH 39/99] Rename 2021-02-25_11-00-00_resources-en to 2021-02-25_11-00-00_resources-en.md --- ..._11-00-00_resources-en => 2021-02-25_11-00-00_resources-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_resources-en => 2021-02-25_11-00-00_resources-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_resources-en b/resources/content/articles/en/2021-02-25_11-00-00_resources-en.md similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_resources-en rename to resources/content/articles/en/2021-02-25_11-00-00_resources-en.md From ca6e0976d7144a4d4810b39f200c81ceaef1557b Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:46:09 +0000 Subject: [PATCH 40/99] Rename 2021-02-25_11-00-00_mallet-end-to-end-en to 2021-02-25_11-00-00_mallet-end-to-end-en.md --- ...-end-to-end-en => 2021-02-25_11-00-00_mallet-end-to-end-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_mallet-end-to-end-en => 2021-02-25_11-00-00_mallet-end-to-end-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en b/resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en.md similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en rename to resources/content/articles/en/2021-02-25_11-00-00_mallet-end-to-end-en.md From 6ad49336b2ada6eaa493fab33a129035e676df6c Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:49:13 +0000 Subject: [PATCH 41/99] Update and rename 2021-02-25_11-00-00_getting-started-en to 2021-02-25_11-00-00_getting-started-en.md --- ...ing-started-en => 2021-02-25_11-00-00_getting-started-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_11-00-00_getting-started-en => 2021-02-25_11-00-00_getting-started-en.md} (73%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en b/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en.md similarity index 73% rename from resources/content/articles/en/2021-02-25_11-00-00_getting-started-en rename to resources/content/articles/en/2021-02-25_11-00-00_getting-started-en.md index a41a31e74..da9dea586 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_getting-started-en.md @@ -1,7 +1,7 @@ --- title: Getting Started description: EVM -parent: 2021-02-25_11-00-00_evm-en +parent: 2021-02-25_11-00-00_evm order: 3 last_updated: "2021-02-25T09:00:00+01:00" --- From a8684775b858b4fe0f8a163299251bd22387bfc8 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:49:46 +0000 Subject: [PATCH 42/99] Rename 2021-02-25_11-00-00_devnet-skill-set-en to 2021-02-25_11-00-00_devnet-skill-set-en.md --- ...et-skill-set-en => 2021-02-25_11-00-00_devnet-skill-set-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_11-00-00_devnet-skill-set-en => 2021-02-25_11-00-00_devnet-skill-set-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en b/resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en.md similarity index 100% rename from resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en rename to resources/content/articles/en/2021-02-25_11-00-00_devnet-skill-set-en.md From 701dcc3eea24eaff19799a94561ed398171f1fce Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:50:08 +0000 Subject: [PATCH 43/99] Update and rename 2021-02-25_11-00-00_block-explorer-en to 2021-02-25_11-00-00_block-explorer-en.md --- ...ock-explorer-en => 2021-02-25_11-00-00_block-explorer-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_11-00-00_block-explorer-en => 2021-02-25_11-00-00_block-explorer-en.md} (91%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en b/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en.md similarity index 91% rename from resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en rename to resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en.md index 558c9a5e5..09f8f89ce 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_block-explorer-en.md @@ -1,7 +1,7 @@ --- title: Block explorer description: EVM getting started -parent: 2021-02-25_11-00-00_getting-started-en +parent: 2021-02-25_11-00-00_getting-started order: 6 last_updated: "2020-12-17T09:00:00+01:00" From 817206a0f42892ef6ef419cbef1c2bd7b129ff69 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:50:37 +0000 Subject: [PATCH 44/99] Update and rename 2021-02-25_11-00-00_about-en to 2021-02-25_11-00-00_about-en.md --- ...-02-25_11-00-00_about-en => 2021-02-25_11-00-00_about-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-25_11-00-00_about-en => 2021-02-25_11-00-00_about-en.md} (71%) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_about-en b/resources/content/articles/en/2021-02-25_11-00-00_about-en.md similarity index 71% rename from resources/content/articles/en/2021-02-25_11-00-00_about-en rename to resources/content/articles/en/2021-02-25_11-00-00_about-en.md index 3cf2ef1ad..fe5eb8caa 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_about-en +++ b/resources/content/articles/en/2021-02-25_11-00-00_about-en.md @@ -1,7 +1,7 @@ --- title: About description: EVM -parent: 2021-02-25_11-00-00_evm-en +parent: 2021-02-25_11-00-00_evm order: 2 last_updated: "2021-02-25T09:00:00+01:00" --- From a57878faad617c7bd8108198fbc1e4f2cad5d21f Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:50:56 +0000 Subject: [PATCH 45/99] Rename 2021-02-25_09-00-00_support-and-help-en to 2021-02-25_09-00-00_support-and-help-en.md --- ...ort-and-help-en => 2021-02-25_09-00-00_support-and-help-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_09-00-00_support-and-help-en => 2021-02-25_09-00-00_support-and-help-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en b/resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en.md similarity index 100% rename from resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en rename to resources/content/articles/en/2021-02-25_09-00-00_support-and-help-en.md From eb5fd1acd71c28af58c78ec08b6d09ca21f1f55d Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:51:17 +0000 Subject: [PATCH 46/99] Rename 2021-02-25_00-00-00_smart_contracts_architecture to 2021-02-25_00-00-00_smart_contracts_architecture.md --- ...ecture => 2021-02-25_00-00-00_smart_contracts_architecture.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-25_00-00-00_smart_contracts_architecture => 2021-02-25_00-00-00_smart_contracts_architecture.md} (100%) diff --git a/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture b/resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture.md similarity index 100% rename from resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture rename to resources/content/articles/en/2021-02-25_00-00-00_smart_contracts_architecture.md From 0b81198c1f89d06dfe88c28d4225581a631c1d63 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:58:31 +0000 Subject: [PATCH 47/99] Update 2021-02-25_11-00-00_resources-en.md --- .../content/articles/en/2021-02-25_11-00-00_resources-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_resources-en.md b/resources/content/articles/en/2021-02-25_11-00-00_resources-en.md index 48867addc..139123d76 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_resources-en.md +++ b/resources/content/articles/en/2021-02-25_11-00-00_resources-en.md @@ -1,7 +1,7 @@ --- title: Resources description: EVM -parent: 2021-02-25_11-00-00_evm-en +parent: 2021-02-25_11-00-00_evm order: 4 last_updated: "2021-02-25T09:00:00+01:00" --- From 0759df0b7a54046b2af7be685b8f28fe3e0eb016 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Wed, 24 Feb 2021 18:59:07 +0000 Subject: [PATCH 48/99] Update 2020-12-14_16-00-00_FAQ_virtual-machines-en.md --- .../articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md b/resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md index 6741010a4..66794ab8c 100644 --- a/resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md +++ b/resources/content/articles/en/2020-12-14_16-00-00_FAQ_virtual-machines-en.md @@ -7,7 +7,7 @@ parent: "2020-05-04_07-00-00_virtual-machines" last_updated: "2021-02-25T11:30:00+01:00" --- -## FAQs for KEVM and IELE +## FAQs for Virtual Machines Note: At this point in time, we are restarting and accelerating the K Ethereum Virtual Machine (KEVM) program *only*. The IELE program will be coming very soon, but you can learn about IELE's features and benefits in this page. From 289cc5be939ba85d5e26adadf20065ac02070b15 Mon Sep 17 00:00:00 2001 From: elviejo79 Date: Wed, 24 Feb 2021 14:08:19 -0600 Subject: [PATCH 49/99] implements the changes made in google drive --- ...02-03_07-00-00_learning-glow-by-example.md | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md index 36976c73e..9eab9aed3 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md @@ -6,25 +6,16 @@ parent: 2020-05-04_06-00-00_glow last_updated: "2021-02-03T07:00:00+01:00" hasNoChildContent: true --- ---- -title: Glow Tutorial -description: Learn Glow using code examples -order: 1 -parent: 2020-05-04_06-00-00_glow -last_updated: "2021-02-03T07:00:00+01:00" -hasNoChildContent: true ---- - # Glow Tutorial -Glow is a language for developing secure decentralized apps (DApps) that can run on different blockchains. +Glow is a language for developing secure decentralized apps (DApps) that can run on different blockchains. In this tutorial, we analyze the sample programs that are provided in the Glow distribution to learn how they work, and how could they can be applied to smart contract and DApp development. -# Buy Signature ([buysig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? +# Buy Signature ([buy_sig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? Let's imagine you want to have your testament notarized. What would you do? @@ -59,7 +50,7 @@ This is the interaction that the `buy_sig.glow` contract represents. 2 @interaction([Buyer, Seller]) 3 let payForSignature = (digest : Digest, price : Assets) => { 4 deposit! Buyer -> price; - 5 @verifiably(Seller) let signature = sign(digest); + 5 @verifiably!(Seller) let signature = sign(digest); 6 publish! Seller -> signature; 7 verify! signature; 8 withdraw! Seller <- price; @@ -84,7 +75,7 @@ There are several things to note: - Identify the participants of a contract with `@interaction` -When an instruction is annotated with the participant's name, that value is private for the participant. Like `@verifiably(Seller)` +When an instruction is annotated with the participant's name, that value is private for the participant. Like `@verifiably!(Seller)` - There are clear instructions for `deposit!` and `withdraw!` @@ -120,7 +111,7 @@ The following Glow code exmaple represents the previous interaction: 3 let coinFlip = (wagerAmount) => { 4 @A assert! canReach(A_wins); 5 @A let randA = randomUInt256(); - 6 @verifiably(A) let commitment = digest(randA); + 6 @verifiably!(A) let commitment = digest(randA); 7 publish! A -> commitment; deposit! A -> wagerAmount; 8 @B assert! canReach(B_wins); 9 @B let randB = randomUInt256(); @@ -194,7 +185,7 @@ How does a player communicate their choice to the blockchain during the game? 9 @A assert! canReach(end, end.outcome == A_Wins); 10 @A let handA = Hand.input("First player, pick your hand"); 11 @A let salt = randomUInt256(); - 12 @verifiably(A) let commitment = digest([salt, handA]); + 12 @verifiably!(A) let commitment = digest([salt, handA]); 13 publish! A -> commitment; deposit! A -> wagerAmount; 14 15 @B assert! canReach(end, end.outcome == B_Wins); @@ -245,7 +236,7 @@ How does a player communicate their choice to the blockchain during the game? - You can use `switch` to do pattern matching -# How to create a deadman switch works? +# How to create a deadman switch? Let's suppose a millionaire unlce has called you because he will give you the password to all his fortune. However, while you are traveling to see your relative he passes away, and only he knew the password for the safe! From 9fae7d81c620c1ab513cbac89922834b8dfd7999 Mon Sep 17 00:00:00 2001 From: elviejo79 Date: Wed, 24 Feb 2021 15:25:26 -0600 Subject: [PATCH 50/99] Split the tutorial into multiple pages --- .../en/2021-02-03_07-00-00_glow000.md | 7 + .../en/2021-02-03_07-00-00_glow010.md | 23 + .../en/2021-02-03_07-00-00_glow020.md | 69 ++ .../en/2021-02-03_07-00-00_glow030.md | 77 +++ .../en/2021-02-03_07-00-00_glow040.md | 87 +++ .../en/2021-02-03_07-00-00_glow050.md | 63 ++ .../en/2021-02-03_07-00-00_glow060.md | 84 +++ .../en/2021-02-03_07-00-00_glow070.md | 105 +++ .../en/2021-02-03_07-00-00_glow080.md | 178 +++++ ...02-03_07-00-00_learning-glow-by-example.md | 650 ------------------ 10 files changed, 693 insertions(+), 650 deletions(-) create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow000.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow010.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow020.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow030.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow040.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow050.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow060.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow070.md create mode 100644 resources/content/articles/en/2021-02-03_07-00-00_glow080.md delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow000.md b/resources/content/articles/en/2021-02-03_07-00-00_glow000.md new file mode 100644 index 000000000..424f8dd4b --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow000.md @@ -0,0 +1,7 @@ +--- +title: Get started +description: Study Glow using code examples +order: 2 +parent: 2020-05-04_06-00-00_glow +last_updated: "2021-02-03T07:00:00+01:00" +--- diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow010.md b/resources/content/articles/en/2021-02-03_07-00-00_glow010.md new file mode 100644 index 000000000..a78e5f34c --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow010.md @@ -0,0 +1,23 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Glow tutorial +description: Installation instructions +order: 1 +--- + +# Glow Tutorial + +Glow is a language for developing secure decentralized apps (DApps) that can run on different blockchains. + +In this tutorial, we analyze the sample programs that are provided in the Glow distribution to learn +how they work, and how could they can be applied to smart contract and DApp development. + +## Installation + +Currently the most reliable way to install Glow is from source with: + +'''sh +curl -L https://glow-lang.org/install/glow-install | sh +''' + +For more information: [INSTALL.md](https://gitlab.com/mukn/glow/-/blob/master/INSTALL.md) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow020.md b/resources/content/articles/en/2021-02-03_07-00-00_glow020.md new file mode 100644 index 000000000..7690d7e09 --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow020.md @@ -0,0 +1,69 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Buy Signature +description: Stuying the buy signature contract +order: 2 +--- +# Buy Signature ([buy_sig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? + +Let's imagine you want to have your testament notarized. What would you do? + +> You first write your testament +> You pay a notary to stamp it +> You store a copy for future reference + +If you think about it, there are many interactions in the world that follow that same process: + +- When your diploma is certified by your University. +- When you renew your driver's license, there is no test, just a renewal stamp. + +We could generalize the process as: + +> A buyer (you in this case) +> Pays a seller +> Takes something, or better yet, a representation of the item (a digest) to a seller. +> The seller can now sign the digest. +> All parties can see that the digest was signed. + +This is the interaction that the `buy_sig.glow` contract represents. + + +## Visualizing the Buyer and Seller interactions + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/buy_sig.png) + + +## Glow code + + 1 #lang glow + 2 @interaction([Buyer, Seller]) + 3 let payForSignature = (digest : Digest, price : Assets) => { + 4 deposit! Buyer -> price; + 5 @verifiably!(Seller) let signature = sign(digest); + 6 publish! Seller -> signature; + 7 verify! signature; + 8 withdraw! Seller <- price; + 9 } + +2. Buyer and seller have agreed to the terms of this sale. They both know what the signature is about, and they want to conduct this sale. +3. The digest of the message to sign is a parameter of the interaction, as is the convened price. +4. The buyer deposits the money according to the price. +5. The seller signs, but it is private only to the seller. +6. The signature is made public for everyone to see. +7. The signature is verified by everyone in a way that the contract enforces. +8. Finally, the money is transferred to the seller. + +There are several things to note: + +1. The code looks a lot like the sequence diagram we created before. +2. The lines of code with @Seller annotation are private. +3. The language itself takes care of requirements. If the buyer never deposits, then the seller never will be able to sign. + + +## Lessons learned + +- Identify the participants of a contract with `@interaction` + +When an instruction is annotated with the participant's name, that value is private for the participant. Like `@verifiably!(Seller)` + +- There are clear instructions for `deposit!` and `withdraw!` diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow030.md b/resources/content/articles/en/2021-02-03_07-00-00_glow030.md new file mode 100644 index 000000000..dd942f11e --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow030.md @@ -0,0 +1,77 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Coin flip +description: How can you flip a coin in Glow? +order: 3 +--- +# How can you flip a coin in Glow? (coinflip.glow) + +Flipping a coin is a game as old as, well, coins. +Alice throws the coin *in the air*, +Bob calls whatever he thinks is going to be the outcome. +The loser pays the winner the agreed amount. + +However, on blockchain, there is no such thing as *in the air*. +So, how can we have something random that has a 50 / 50 chance for Alice? + +For example, Alice flips her coin. +Bob flips his coin +And then Alice wins if both coins match. +Or Bob wins if the coins are different. +Both outcomes have a 50 / 50 chance of happening. + + +## Sequence diagram + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png) + + +## Glow code + +The following Glow code exmaple represents the previous interaction: + + 1 #lang glow + 2 @interaction([A, B]) + 3 let coinFlip = (wagerAmount) => { + 4 @A assert! canReach(A_wins); + 5 @A let randA = randomUInt256(); + 6 @verifiably!(A) let commitment = digest(randA); + 7 publish! A -> commitment; deposit! A -> wagerAmount; + 8 @B assert! canReach(B_wins); + 9 @B let randB = randomUInt256(); + 10 publish! B -> randB; deposit! B -> wagerAmount; + 11 publish! A -> randA; + 12 verify! commitment; + 13 if (((randA ^^^ randB) &&& 1) == 0) { + 14 A_wins: withdraw! A <- 2*wagerAmount + 15 } else { + 16 B_wins: withdraw! B <- 2*wagerAmount + 17 } + 18 }; + +1. Every Glow program starts with the #lang glow identification +2. We know that two actors, A and B (Alice and Bob), are going to participate in this contract +3. coinFlip needs to know the amount each player is going to bet to get started. +4. Alice needs to be assured that there is a state where she can win. Ie. `assert!` makes sure that the program can reach the label `A_wins` +5. Alice draws random numbers between 0 and 2256. Approx. 78 decimal digits. +6. Alice stores in the commitment value the digest of the random number she generated. +7. She publishes her commitment on the blockchain and deposits her wager. + +Now it is Bob's turn: + +8. Bob makes sure that it is possible to get to the `B_wins` label to know that he can win. +9. Bob flips a coin. i.e., draws a random number between 0 and 2256. +10. Bob publishes the coin that he flipped and deposits his wager. +11. Alice publishes the coin that she threw. +12. We `verify!` that the commitment matches the coin that she threw. +13. By doing a bitwise XOR of the random numbers thrown by Alice and Bob, we find that they match +14. Alice wins and withdraws two times the wager +15. However, If the `xor` doesn't match, Bob wins +16. In addition, Bob gets double the bet. + + +## Lessons learned + +- You can generate random numbers with `randomUInt256` +- You can `assert!` you can reach a label such as `A_wins:` +- There are bitwise operations with like `^^^` and `&&&` diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow040.md b/resources/content/articles/en/2021-02-03_07-00-00_glow040.md new file mode 100644 index 000000000..ae5f45817 --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow040.md @@ -0,0 +1,87 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Rock, Paper Scissors +description: Playing Rock, Paper, Scissors (rps-min.glow)? +order: 4 +--- +# Playing Rock, Paper, Scissors (rps-min.glow)? + +Rock, paper, scissors is the classic children's game where each child shows what they have chosen at the same time. +The decision on who has won is based on the following rules: + +- Both selected the same: Draw +- Rock beats scissors +- Paper beats rock +- Scissors beats paper + +How con you code this in Glow if there is no *at the same time*. +How does a player communicate their choice to the blockchain during the game? + + +## Visualization + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png) + + +## Glow code + + 1 #lang glow + 2 data Hand = | Rock | Paper | Scissors; + 3 data Outcome = | B_Wins | Draw | A_Wins; + 4 let winner = (handA : Hand, handB : Hand) : Outcome => { + 5 Outcome.ofNat((Hand.toNat(handA) + (4 - Hand.toNat(handB))) % 3) } + 6 + 7 @interaction([A, B]) + 8 let rockPaperScissors = (wagerAmount) => { + 9 @A assert! canReach(end, end.outcome == A_Wins); + 10 @A let handA = Hand.input("First player, pick your hand"); + 11 @A let salt = randomUInt256(); + 12 @verifiably!(A) let commitment = digest([salt, handA]); + 13 publish! A -> commitment; deposit! A -> wagerAmount; + 14 + 15 @B assert! canReach(end, end.outcome == B_Wins); + 16 @B let handB = Hand.input("Second player, pick your hand"); + 17 publish! B -> handB; deposit! B -> wagerAmount; + 18 + 19 publish! A -> salt, handA; + 20 verify! commitment; + 21 let outcome = winner(handA, handB); + 22 end: switch(outcome) { + 23 | A_Wins => withdraw! A <- 2*wagerAmount + 24 | B_Wins => withdraw! B <- 2*wagerAmount + 25 | Draw => withdraw! A <- wagerAmount; withdraw! B <- wagerAmount }} + +2. A `Hand` can only be `Rock, Paper or Scissors` +3. There are only three possible `Outcome` either `B_wins`, `A_wins`, or its a `Draw` +4. Now define a function `winner`, that when given two hands can determine the `Outcome` +5. This is an arithmetic trick that translates each of the nine possible hand combinations to three possible outcomes +6. + +7. Alice and Bob use this contract +8. Declare the `rockPaperScissors` contract that has the `wagerAmount` +9. `@Alice` makes sure (`assert!`) that it's possible to reach the `end:` label +10. `@Alice` asks (`input`) and stores the value of her Hand. +11. `@Alice` creates a random value (`salt`) that will be used to obfuscate her Hand +12. `@Alice` store the obfuscated value of her Hand in a `verifiably` commitment +13. `@Alice` makes her commitment public and `deposit!` her wage. +14. + +15. `@Bob` makes sure he can reach the `end.outcome` where he wins +16. `@Bob` can `input` what hand he chooses to play +17. `@Bob` publishes his Hand and deposits his wager +18. + +19. Now it's possible to publish the `salt` and in the next step, use it to +20. `verify!` that the `commitment` was obfuscated with the salt +21. now we calculate the `outcome` as the result of evaluating the `winner` function with both hands. +22. `switch` for pattern matching, it's possible to select the appropriate outcome. +23. if `outcome` is `A_wins` `withdraw` to Alice both wages. +24. if `outcome` is `B_wins` `withdraw` to Bob both wages. +25. if `outcome` is `Draw` `withdraw` to give back their money to Alice and Bob. + + +## Lessons learned + +- You can define your data types with `data Hand` +- You can define smaller functions that are used later in the contract. Like: `let winner = (handA:Hand, handB:Hand)` +- You can use `switch` to do pattern matching diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow050.md b/resources/content/articles/en/2021-02-03_07-00-00_glow050.md new file mode 100644 index 000000000..29fdac203 --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow050.md @@ -0,0 +1,63 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Deadman switch +description: How to create a deadman switch? +order: 5 +--- +# How to create a deadman switch? + +Let's suppose a millionaire unlce has called you because he will give you the password to all his fortune. +However, while you are traveling to see your relative he passes away, and only he knew the password for the safe! + +Six months later, you get an email with the password for the safe and it turns out that your uncle had a *dead man switch* that would automatically reveal the password. + +In this contract, we are going to see how your uncle implemented that contract in Glow. + +## Visualization + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png) + + +## Glow Code + + 1 #lang glow + 2 // -*- JavaScript -*- + 3 // Inspired by https://github.com/KarolTrzeszczkowski/Electron-Cash-Last-Will-Plugin + 4 + 5 data Command = Withdraw(x : Nat) | Inherit(x : Nat) + 6 + 7 @interaction([Owner, Heir]) + 8 let deadManSwitch = (expirationDelay) => { + 9 let rec loop = (expirationTimestamp) => + 10 choice { + 11 | @_ deposit! x ; + 12 loop (expirationtimestamp); + 13 | @owner publish! withdraw(x); + 14 withdraw! owner <- x ; + 15 loop (now() + expirationdelay); + 16 | @heir publish! inherit(x); + 17 require! now() >= expirationtimestamp; + 18 withdraw! heir <- x; + 19 }; + 20 loop(now() + expirationdelay); + 21 } + +- 5 on this contract, there are only two actions, either withdraw or inherit. +- 7 and there are only two participants, the Owner of the fortune and you. +- 8 When creating the contract, the Owner must say how often he wants it to renew. For example, every six months. +- 20 The first time we go into the loop, it starts +- 9 Now the `loop` is a function that can call itself (recursive). +- 10 Is like pattern matching but based on whom performs the action +- 11 If there is a deposit, the contract continues. +- 13 In order to show that it's still alive, the Owner publishes on the blockchain that he wants to withdraw a little bit of the funds in the contract. +- 15 It renews the *dead man switch* with a new deadline. +- 16 When the `@heir` signals on the blockchain that is ready to inherit. + +The contract checks if the current block is past the expiration day. +If this is the case, the funds are released to the `heir`. + + +## Lessons learned + +- How to use explicit timestamps +- How to use recursive functions diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow060.md b/resources/content/articles/en/2021-02-03_07-00-00_glow060.md new file mode 100644 index 000000000..678188932 --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow060.md @@ -0,0 +1,84 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Simple Auction +description: How does the Simple Auction (auction.glow) contract work? +order: 6 +--- +# How does the Simple Auction (auction.glow) contract work? + +Imagine an auction where each one of the bidders tries to outbid the previous bidder. +However, in a blockchain auction, each bidder has to declare the money first to become the top bidder. +They get their money back when they are outbid. + + +## Visualization + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png) + + +## Glow code + + 1 #lang glow + 2 data Action = Bid(TokenAmount) | BuyItNow | Close; + 3 + 4 @interaction([Seller]) + 5 let simpleAuction = (goods : Assets, expirationTime : Timestamp, buyItNowPrice: TokenAmount) => { + 6 require! Assets.is_positive(goods); + 7 require! expirationTime > currentTime(); + 8 deposit! Seller -> goods; + 9 + 10 @interaction([Seller, CurrentBidder]) + 11 let rec auction = (currentBid) => { + 12 assert! @deposited == goods + currentBid; + 13 choice { + 14 | ForAllParticipant (NewBidder) { + 15 @NewBidder bid = Bid(input(["Enter next bid"], TokenAmout)); + 16 publish! NewBidder -> bid ; deposit! NewBidder -> bid; + 17 @NewBidder assume! @value(goods) > @value(bid); + 18 require! currentTime() < expirationTime; + 19 require! bid > currentBid; + 20 require! bid < buyItNowPrice; + 21 withdraw! CurrentBidder <- currentBid; + 22 @interaction([Seller, NewBidder]) auction(bid); + 23 | ForAllParticipant (NewBidder) { + 24 publish! NewBidder -> BuyItNow ; deposit! NewBidder -> buyItNowPrice; + 25 require! currentTime() < expirationTime; + 26 withdraw! NewBidder <- goods; + 27 withdraw! CurrentBidder <- currentBid; + 28 withdraw! Seller <- buyItNowPrice; + 29 | @_ { publish! Close; } => + 30 require! currentTime() >= expirationTime; + 31 withdraw! Seller <- currentBid; + 32 withdraw! CurrentBidder <- goods; + 33 }; + 34 @interaction([Seller, Seller]) auction(0); + 35 } + +- 2 Declares the possible commands that could be performed on this contract +- 4 Only the Seller can create an auction +- **5:** In order to create an auction, a Seller must provide: + +The `Goods` that could be anything that can be represented as an asset, +an `expirationTime` at which point the auction is over and +a price at which to buy it immediately `buyItNowPrice`. + +- 8 The Seller must deposit the goods in the smart contract. This could, for example, a photograph. +- 34 The real auction begins at 0, and the "first bidder" is the Seller himself. +- 10 The real auction is an interaction between the Seller and the Current bidder. +- 11 This function is recursive, so it can call itself. +- 12 A sanity check, let's make sure that the amount deposited to the contract is the goods plus the current bidder. +- 14 This is key in this contract; anyone that bids may become a participant. +- 15 The contract as the new participant for their bid. +- 16 The new bid should be public and it's deposited into the contract. +- 19 The new bid must be bigger than the current one in order to replace it. +- 21 The previous highest bidder gets its money back since it has been replaced by the new bid. +- 22 Now the auction may continue, recursively, with a new highest bidder. +- 23 If the new bidder, reaches the *buy it now* price. Then the auction is settled right now. +- 29 If the expiration time is reached, then the auction is settled. + + +## Lessons learned + +- Recursive function definitions +- How to involve participants that are not known beforehand. +- How to use an expiration date diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow070.md b/resources/content/articles/en/2021-02-03_07-00-00_glow070.md new file mode 100644 index 000000000..b9ad3f7c7 --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow070.md @@ -0,0 +1,105 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Crowdfund +description: How does Crowdfunding.glow work? +order: 7 +--- +# How does Crowdfunding.glow work? + +In this day and age, crowdfunding campaigns are well known. +Platforms like kickstarter.com and GoFund.me have made the crowdfunding model well known across the world +as an excellent way to bring together the resources of several parties that do not know each other +and yet are willing to contribute some money towards a common goal. + + +## Glow code + + 1 data Action = Pledge(TokenAmount) | Close | Reclaim(TokenAmount); + 2 + 3 let platformCommission amount = quotient(amount, 100); + 4 + 5 @interaction + 6 let crowdfunding = (target: TokenAmount, + 7 expirationTime : Timestamp) => { + 8 require! expirationTime > currentTime(); + 9 + 10 let rec crowdfund = (ledger : Table(TokenAmount <- Participant), + 11 totalPledged: TokenAmount) => { + 12 assert! totalPledged == totalAmount(ledger); + 13 choice { + 14 | ForAllParticipant (NewPledger) { + 15 @NewPledger amount = + 16 input(["Enter next pledge"], TokenAmount); + 17 publish! NewPledger -> Pledge(amount); + 18 deposit! NewPledger -> amount; + 19 require! currentTime() < expirationTime; + 20 crowdfund(Table.add(ledger, NewPledger, amount), + 21 totalPledged + amount); + 22 + 23 | publish! Organizer -> Success; + 24 require! currentTime() >= expirationTime; + 25 require! totalPledged >= target; + 26 let commission = platformCommission(totalPledged); + 27 withdraw! Platform <- commission; + 28 withdraw! Organizer <- totalPledged - commission; + 29 + 30 | ForAllParticipant(Pledger) + 31 publish! Pledger -> Reclaim(amount); + 32 require! currentTime() >= expirationTime; + 33 require! totalPledged < target; + 34 require! Table.get(ledger, Pledger) == amount; + 35 withdraw! Pledger <- amount; //(ref: return_amount_to_pledger) + 36 crowdfund(Table.remove(ledger, Pledger), //(ref: remove_pledger_from_ledger) + 37 totalPledged - amount); + 38 } + 39 crowdfund({}, 0); + 40 } + +- 7 When creating a campaign, there is a goal and an expiration time. + +- 11 We create a `ledger` where we record the `Pledgers` and the total amoun the campaign has raised so far + +Now three things can happen: + +- There is a new pledge +- The campaign was a successor +- A pledger reclaims a refund + +Let's look at all three in detail. + + +### Dealing with a new pledge + +Any participant can pledge 14. +The `NewPledger` must `deposit!` her amount to the contract 18. +And the pledge is stored in the `Ledger` 20. + + +### Campaign is successful + +23 When the organizer declares the campaign a success. +24 We must make sure the deadline for the campaign has passed and +25 The `totalPledged` surpassed the `target`. + + +### Pledger requests a reimbursement + +When a pledger requests a reimbursement 30. +We check that the expiration date has passed 32 and +that the goal wasn't achieved 33 . +Then we check that the amount that is reclaiming is the same we have stored in the Ledger 34. +We return the amount to the Pledger and remove it from the Ledger. + + +## Lessons learned + +- Explicit timeout +- Unrestricted open set of participants +- Choice restricted to timeouts and open participation + + +## Challenge + +Can you write a version of this contract that does the following: +a) Automatically decides if the campaign was successful or not (given the timeout). +b) Reimburses all the pledges automatically. diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow080.md b/resources/content/articles/en/2021-02-03_07-00-00_glow080.md new file mode 100644 index 000000000..30127c526 --- /dev/null +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow080.md @@ -0,0 +1,178 @@ +--- +parent: 2021-02-03_07-00-00_glow000 +title: Challenge +description: Translate a Solidity smart contract to Glow +order: 8 +--- +# Challenge: Translate a Solidity smart contract to Glow + +In order to learn something new, we normally try to learn it refers to something we already know. +That's why in this article, we are going to learn the Glow smart contract language +by studying an example in Solidity and then translating it to Glow + + +## The Ballot example + +Ballot.sol is the first program that loads when looking going to the Remix IDE + + pragma solidity >=0.7.0 <0.8.0; + contract Ballot { + +Declare a struct called Voter that is a complex type +consisting of the weight of a vote, a Boolean voted, +the address of the Voter, and an index called vote. + + struct Voter { + uint weight;// Weight is accumulated by delegation + bool voted; // if true, that person already voted + address delegate;// person delegated to + uint vote; // index of the voted proposal + } + +You have an address type called chairperson. + + address chairperson; + +You have a mapping where you map and address with a voter + + mapping(address => Voter) voters; + +You also create an array of proposals where each proposal is a complex type struct. + + Proposal[] proposals; + + struct Proposal { + // If you can limit the length to a certain number of bytes, + // always use one of bytes1 to bytes32 because they are much cheaper + bytes32 name; // short name (up to 32 bytes) + uint voteCount;// number of accumulated votes + } + +In the constructor Ballot, you initialize the chairperson as the message sender with weight 1. +You also create a list of proposals. + + constructor(bytes32[] memory proposalNames) { + chairperson = msg.sender; + voters[chairperson].weight = 1; + + for (uint i = 0; i < proposalNames.length; i++) { + // 'Proposal({...})' creates a temporary + // Proposal object and 'proposals.push(...)' + // appends it to the end of 'proposals'. + proposals.push(Proposal({ + name: proposalNames[i], + voteCount: 0 + })); + } + } + +Give the `Voter` the right to vote on this ballot. +It can only be called by the `Chairperson`. +Validate that the voters have not voted yet and assign voters a weight. + + function giveRightToVote(address voter) public { + require( + msg.sender == chairperson, + "Only chairperson can give right to vote." + ); + require( + !voters[voter].voted, + "The voter already voted." + ); + require(voters[voter].weight == 0, + "the voter already had voting rights"); + voters[voter].weight = 1; + } + +Then the delegate() function delegates your vote to the Voter $(to) after a couple of validations +such as the message sender is not the to address has not voted. + + function delegate(address to) public { + Voter storage sender = voters[msg.sender]; + require(!sender.voted, "You already voted."); + require(to != msg.sender, "Self-delegation is disallowed."); + + while (voters[to].delegate != address(0)) { + to = voters[to].delegate; + + // We found a loop in the Delegation, not allowed. + require(to != msg.sender, "Found loop in delegation."); + } + sender.voted = true; + sender.delegate = to; + Voter storage delegate_ = voters[to]; + if (delegate_.voted) { + // If the delegate already voted, + // directly add to the number of votes + proposals[delegate_.vote].voteCount += sender.weight; + } else { + // If the delegate did not vote yet, + // add to her weight. + delegate_.weight += sender.weight; + } + } + +Give your vote (including votes delegated to you) to proposal + + function vote(uint proposal) public { + Voter storage sender = voters[msg.sender]; + require(sender.weight != 0, "Has no right to vote"); + require(!sender.voted, "Already voted."); + sender.voted = true; + sender.vote = proposal; + + // If 'proposal' is out of the range of the array, + // this will throw automatically and revert all + // changes. + proposals[proposal].voteCount += sender.weight; + } + +Find which is the proposal with the most votes. + + function winningProposal() public view + returns (uint winningProposal_) + { + uint winningVoteCount = 0; + for (uint p = 0; p < proposals.length; p++) { + if (proposals[p].voteCount > winningVoteCount) { + winningVoteCount = proposals[p].voteCount; + winningProposal_ = p; + } + } + } + +Get the name of the winning proposal + + function winnerName() public view + returns (bytes32 winnerName_) + { + winnerName_ = proposals[winningProposal()].name; + } + } + + +## Visualization + +By reading the previous contract, we can identify the following actors and flow: +The `Chairman` creates a contract with a defined number of options. +Then gives names to each option. +And grants voting rights to voters. +A voter (Bob in this diagram) can delegate his vote to another voter. +Voters vote for one of the options by its number. +Then everyone can ask who is winning by the one that has more votes. + +![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/ballot.png) + + +## How does the contract look in Glow? + +Now it is your turn. How does the previous smart contract look in Glow? + +Here are a few ideas on how you could get started with such a program: + +- One known proposal, one known voter +- Multiple known proposals, One known voter +- Multiple known proposals, Three known voters +- Multiple known proposals, Three known voters, with delegation +- Multiple known proposals, unknown voters, with delegation +- Multiple known proposals, unknown voters, with delegation, with giving voting rights diff --git a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md b/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md deleted file mode 100644 index 9eab9aed3..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_learning-glow-by-example.md +++ /dev/null @@ -1,650 +0,0 @@ ---- -title: Glow Tutorial -description: Study Glow using code examples -order: 2 -parent: 2020-05-04_06-00-00_glow -last_updated: "2021-02-03T07:00:00+01:00" -hasNoChildContent: true ---- - -# Glow Tutorial - -Glow is a language for developing secure decentralized apps (DApps) that can run on different blockchains. - -In this tutorial, we analyze the sample programs that are provided in the Glow distribution to learn -how they work, and how could they can be applied to smart contract and DApp development. - - -# Buy Signature ([buy_sig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? - -Let's imagine you want to have your testament notarized. What would you do? - -> You first write your testament -> You pay a notary to stamp it -> You store a copy for future reference - -If you think about it, there are many interactions in the world that follow that same process: - -- When your diploma is certified by your University. -- When you renew your driver's license, there is no test, just a renewal stamp. - -We could generalize the process as: - -> A buyer (you in this case) -> Pays a seller -> Takes something, or better yet, a representation of the item (a digest) to a seller. -> The seller can now sign the digest. -> All parties can see that the digest was signed. - -This is the interaction that the `buy_sig.glow` contract represents. - - -## Visualizing the Buyer and Seller interactions - -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/buy_sig.png) - - -## Glow code - - 1 #lang glow - 2 @interaction([Buyer, Seller]) - 3 let payForSignature = (digest : Digest, price : Assets) => { - 4 deposit! Buyer -> price; - 5 @verifiably!(Seller) let signature = sign(digest); - 6 publish! Seller -> signature; - 7 verify! signature; - 8 withdraw! Seller <- price; - 9 } - -2. Buyer and seller have agreed to the terms of this sale. They both know what the signature is about, and they want to conduct this sale. -3. The digest of the message to sign is a parameter of the interaction, as is the convened price. -4. The buyer deposits the money according to the price. -5. The seller signs, but it is private only to the seller. -6. The signature is made public for everyone to see. -7. The signature is verified by everyone in a way that the contract enforces. -8. Finally, the money is transferred to the seller. - -There are several things to note: - -1. The code looks a lot like the sequence diagram we created before. -2. The lines of code with @Seller annotation are private. -3. The language itself takes care of requirements. If the buyer never deposits, then the seller never will be able to sign. - - -## Lessons learned - -- Identify the participants of a contract with `@interaction` - -When an instruction is annotated with the participant's name, that value is private for the participant. Like `@verifiably!(Seller)` - -- There are clear instructions for `deposit!` and `withdraw!` - - -# How can you flip a coin in Glow? (coinflip.glow) - -Flipping a coin is a game as old as, well, coins. -Alice throws the coin *in the air*, -Bob calls whatever he thinks is going to be the outcome. -The loser pays the winner the agreed amount. - -However, on blockchain, there is no such thing as *in the air*. -So, how can we have something random that has a 50 / 50 chance for Alice? - -For example, Alice flips her coin. -Bob flips his coin -And then Alice wins if both coins match. -Or Bob wins if the coins are different. -Both outcomes have a 50 / 50 chance of happening. - - -## Sequence diagram - -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png) - - -## Glow code - -The following Glow code exmaple represents the previous interaction: - - 1 #lang glow - 2 @interaction([A, B]) - 3 let coinFlip = (wagerAmount) => { - 4 @A assert! canReach(A_wins); - 5 @A let randA = randomUInt256(); - 6 @verifiably!(A) let commitment = digest(randA); - 7 publish! A -> commitment; deposit! A -> wagerAmount; - 8 @B assert! canReach(B_wins); - 9 @B let randB = randomUInt256(); - 10 publish! B -> randB; deposit! B -> wagerAmount; - 11 publish! A -> randA; - 12 verify! commitment; - 13 if (((randA ^^^ randB) &&& 1) == 0) { - 14 A_wins: withdraw! A <- 2*wagerAmount - 15 } else { - 16 B_wins: withdraw! B <- 2*wagerAmount - 17 } - 18 }; - -1. Every Glow program starts with the #lang glow identification -2. We know that two actors, A and B (Alice and Bob), are going to participate in this contract -3. coinFlip needs to know the amount each player is going to bet to get started. -4. Alice needs to be assured that there is a state where she can win. Ie. `assert!` makes sure that the program can reach the label `A_wins` -5. Alice draws random numbers between 0 and 2256. Approx. 78 decimal digits. -6. Alice stores in the commitment value the digest of the random number she generated. -7. She publishes her commitment on the blockchain and deposits her wager. - -Now it is Bob's turn: - -8. Bob makes sure that it is possible to get to the `B_wins` label to know that he can win. -9. Bob flips a coin. i.e., draws a random number between 0 and 2256. -10. Bob publishes the coin that he flipped and deposits his wager. -11. Alice publishes the coin that she threw. -12. We `verify!` that the commitment matches the coin that she threw. -13. By doing a bitwise XOR of the random numbers thrown by Alice and Bob, we find that they match -14. Alice wins and withdraws two times the wager -15. However, If the `xor` doesn't match, Bob wins -16. In addition, Bob gets double the bet. - - -## Lessons learned - -- You can generate random numbers with `randomUInt256` -- You can `assert!` you can reach a label such as `A_wins:` -- There are bitwise operations with like `^^^` and `&&&` - - -# Playing Rock, Paper, Scissors (rps-min.glow)? - -Rock, paper, scissors is the classic children's game where each child shows what they have chosen at the same time. -The decision on who has won is based on the following rules: - -- Both selected the same: Draw -- Rock beats scissors -- Paper beats rock -- Scissors beats paper - -How con you code this in Glow if there is no *at the same time*. -How does a player communicate their choice to the blockchain during the game? - - -## Visualization - -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png) - - -## Glow code - - 1 #lang glow - 2 data Hand = | Rock | Paper | Scissors; - 3 data Outcome = | B_Wins | Draw | A_Wins; - 4 let winner = (handA : Hand, handB : Hand) : Outcome => { - 5 Outcome.ofNat((Hand.toNat(handA) + (4 - Hand.toNat(handB))) % 3) } - 6 - 7 @interaction([A, B]) - 8 let rockPaperScissors = (wagerAmount) => { - 9 @A assert! canReach(end, end.outcome == A_Wins); - 10 @A let handA = Hand.input("First player, pick your hand"); - 11 @A let salt = randomUInt256(); - 12 @verifiably!(A) let commitment = digest([salt, handA]); - 13 publish! A -> commitment; deposit! A -> wagerAmount; - 14 - 15 @B assert! canReach(end, end.outcome == B_Wins); - 16 @B let handB = Hand.input("Second player, pick your hand"); - 17 publish! B -> handB; deposit! B -> wagerAmount; - 18 - 19 publish! A -> salt, handA; - 20 verify! commitment; - 21 let outcome = winner(handA, handB); - 22 end: switch(outcome) { - 23 | A_Wins => withdraw! A <- 2*wagerAmount - 24 | B_Wins => withdraw! B <- 2*wagerAmount - 25 | Draw => withdraw! A <- wagerAmount; withdraw! B <- wagerAmount }} - -2. A `Hand` can only be `Rock, Paper or Scissors` -3. There are only three possible `Outcome` either `B_wins`, `A_wins`, or its a `Draw` -4. Now define a function `winner`, that when given two hands can determine the `Outcome` -5. This is an arithmetic trick that translates each of the nine possible hand combinations to three possible outcomes -6. - -7. Alice and Bob use this contract -8. Declare the `rockPaperScissors` contract that has the `wagerAmount` -9. `@Alice` makes sure (`assert!`) that it's possible to reach the `end:` label -10. `@Alice` asks (`input`) and stores the value of her Hand. -11. `@Alice` creates a random value (`salt`) that will be used to obfuscate her Hand -12. `@Alice` store the obfuscated value of her Hand in a `verifiably` commitment -13. `@Alice` makes her commitment public and `deposit!` her wage. -14. - -15. `@Bob` makes sure he can reach the `end.outcome` where he wins -16. `@Bob` can `input` what hand he chooses to play -17. `@Bob` publishes his Hand and deposits his wager -18. - -19. Now it's possible to publish the `salt` and in the next step, use it to -20. `verify!` that the `commitment` was obfuscated with the salt -21. now we calculate the `outcome` as the result of evaluating the `winner` function with both hands. -22. `switch` for pattern matching, it's possible to select the appropriate outcome. -23. if `outcome` is `A_wins` `withdraw` to Alice both wages. -24. if `outcome` is `B_wins` `withdraw` to Bob both wages. -25. if `outcome` is `Draw` `withdraw` to give back their money to Alice and Bob. - - -## Lessons learned - -- You can define your data types with `data Hand` -- You can define smaller functions that are used later in the contract. Like: `let winner = (handA:Hand, handB:Hand)` -- You can use `switch` to do pattern matching - - -# How to create a deadman switch? - -Let's suppose a millionaire unlce has called you because he will give you the password to all his fortune. -However, while you are traveling to see your relative he passes away, and only he knew the password for the safe! - -Six months later, you get an email with the password for the safe and it turns out that your uncle had a *dead man switch* that would automatically reveal the password. - -In this contract, we are going to see how your uncle implemented that contract in Glow. - -## Visualization - -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png) - - -## Glow Code - - 1 #lang glow - 2 // -*- JavaScript -*- - 3 // Inspired by https://github.com/KarolTrzeszczkowski/Electron-Cash-Last-Will-Plugin - 4 - 5 data Command = Withdraw(x : Nat) | Inherit(x : Nat) - 6 - 7 @interaction([Owner, Heir]) - 8 let deadManSwitch = (expirationDelay) => { - 9 let rec loop = (expirationTimestamp) => - 10 choice { - 11 | @_ deposit! x ; - 12 loop (expirationtimestamp); - 13 | @owner publish! withdraw(x); - 14 withdraw! owner <- x ; - 15 loop (now() + expirationdelay); - 16 | @heir publish! inherit(x); - 17 require! now() >= expirationtimestamp; - 18 withdraw! heir <- x; - 19 }; - 20 loop(now() + expirationdelay); - 21 } - -- 5 on this contract, there are only two actions, either withdraw or inherit. -- 7 and there are only two participants, the Owner of the fortune and you. -- 8 When creating the contract, the Owner must say how often he wants it to renew. For example, every six months. -- 20 The first time we go into the loop, it starts -- 9 Now the `loop` is a function that can call itself (recursive). -- 10 Is like pattern matching but based on whom performs the action -- 11 If there is a deposit, the contract continues. -- 13 In order to show that it's still alive, the Owner publishes on the blockchain that he wants to withdraw a little bit of the funds in the contract. -- 15 It renews the *dead man switch* with a new deadline. -- 16 When the `@heir` signals on the blockchain that is ready to inherit. - -The contract checks if the current block is past the expiration day. -If this is the case, the funds are released to the `heir`. - - -## Lessons learned - -- How to use explicit timestamps -- How to use recursive functions - - -# How does the Simple Auction (auction.glow) contract work? - -Imagine an auction where each one of the bidders tries to outbid the previous bidder. -However, in a blockchain auction, each bidder has to declare the money first to become the top bidder. -They get their money back when they are outbid. - - -## Visualization - -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png) - - -## Glow code - - 1 #lang glow - 2 data Action = Bid(TokenAmount) | BuyItNow | Close; - 3 - 4 @interaction([Seller]) - 5 let simpleAuction = (goods : Assets, expirationTime : Timestamp, buyItNowPrice: TokenAmount) => { - 6 require! Assets.is_positive(goods); - 7 require! expirationTime > currentTime(); - 8 deposit! Seller -> goods; - 9 - 10 @interaction([Seller, CurrentBidder]) - 11 let rec auction = (currentBid) => { - 12 assert! @deposited == goods + currentBid; - 13 choice { - 14 | ForAllParticipant (NewBidder) { - 15 @NewBidder bid = Bid(input(["Enter next bid"], TokenAmout)); - 16 publish! NewBidder -> bid ; deposit! NewBidder -> bid; - 17 @NewBidder assume! @value(goods) > @value(bid); - 18 require! currentTime() < expirationTime; - 19 require! bid > currentBid; - 20 require! bid < buyItNowPrice; - 21 withdraw! CurrentBidder <- currentBid; - 22 @interaction([Seller, NewBidder]) auction(bid); - 23 | ForAllParticipant (NewBidder) { - 24 publish! NewBidder -> BuyItNow ; deposit! NewBidder -> buyItNowPrice; - 25 require! currentTime() < expirationTime; - 26 withdraw! NewBidder <- goods; - 27 withdraw! CurrentBidder <- currentBid; - 28 withdraw! Seller <- buyItNowPrice; - 29 | @_ { publish! Close; } => - 30 require! currentTime() >= expirationTime; - 31 withdraw! Seller <- currentBid; - 32 withdraw! CurrentBidder <- goods; - 33 }; - 34 @interaction([Seller, Seller]) auction(0); - 35 } - -- 2 Declares the possible commands that could be performed on this contract -- 4 Only the Seller can create an auction -- **5:** In order to create an auction, a Seller must provide: - -The `Goods` that could be anything that can be represented as an asset, -an `expirationTime` at which point the auction is over and -a price at which to buy it immediately `buyItNowPrice`. - -- 8 The Seller must deposit the goods in the smart contract. This could, for example, a photograph. -- 34 The real auction begins at 0, and the "first bidder" is the Seller himself. -- 10 The real auction is an interaction between the Seller and the Current bidder. -- 11 This function is recursive, so it can call itself. -- 12 A sanity check, let's make sure that the amount deposited to the contract is the goods plus the current bidder. -- 14 This is key in this contract; anyone that bids may become a participant. -- 15 The contract as the new participant for their bid. -- 16 The new bid should be public and it's deposited into the contract. -- 19 The new bid must be bigger than the current one in order to replace it. -- 21 The previous highest bidder gets its money back since it has been replaced by the new bid. -- 22 Now the auction may continue, recursively, with a new highest bidder. -- 23 If the new bidder, reaches the *buy it now* price. Then the auction is settled right now. -- 29 If the expiration time is reached, then the auction is settled. - - -## Lessons learned - -- Recursive function definitions -- How to involve participants that are not known beforehand. -- How to use an expiration date - - -# How does Crowdfunding.glow work? - -In this day and age, crowdfunding campaigns are well known. -Platforms like kickstarter.com and GoFund.me have made the crowdfunding model well known across the world -as an excellent way to bring together the resources of several parties that do not know each other -and yet are willing to contribute some money towards a common goal. - - -## Glow code - - 1 data Action = Pledge(TokenAmount) | Close | Reclaim(TokenAmount); - 2 - 3 let platformCommission amount = quotient(amount, 100); - 4 - 5 @interaction - 6 let crowdfunding = (target: TokenAmount, - 7 expirationTime : Timestamp) => { - 8 require! expirationTime > currentTime(); - 9 - 10 let rec crowdfund = (ledger : Table(TokenAmount <- Participant), - 11 totalPledged: TokenAmount) => { - 12 assert! totalPledged == totalAmount(ledger); - 13 choice { - 14 | ForAllParticipant (NewPledger) { - 15 @NewPledger amount = - 16 input(["Enter next pledge"], TokenAmount); - 17 publish! NewPledger -> Pledge(amount); - 18 deposit! NewPledger -> amount; - 19 require! currentTime() < expirationTime; - 20 crowdfund(Table.add(ledger, NewPledger, amount), - 21 totalPledged + amount); - 22 - 23 | publish! Organizer -> Success; - 24 require! currentTime() >= expirationTime; - 25 require! totalPledged >= target; - 26 let commission = platformCommission(totalPledged); - 27 withdraw! Platform <- commission; - 28 withdraw! Organizer <- totalPledged - commission; - 29 - 30 | ForAllParticipant(Pledger) - 31 publish! Pledger -> Reclaim(amount); - 32 require! currentTime() >= expirationTime; - 33 require! totalPledged < target; - 34 require! Table.get(ledger, Pledger) == amount; - 35 withdraw! Pledger <- amount; //(ref: return_amount_to_pledger) - 36 crowdfund(Table.remove(ledger, Pledger), //(ref: remove_pledger_from_ledger) - 37 totalPledged - amount); - 38 } - 39 crowdfund({}, 0); - 40 } - -- 7 When creating a campaign, there is a goal and an expiration time. - -- 11 We create a `ledger` where we record the `Pledgers` and the total amoun the campaign has raised so far - -Now three things can happen: - -- There is a new pledge -- The campaign was a successor -- A pledger reclaims a refund - -Let's look at all three in detail. - - -### Dealing with a new pledge - -Any participant can pledge 14. -The `NewPledger` must `deposit!` her amount to the contract 18. -And the pledge is stored in the `Ledger` 20. - - -### Campaign is successful - -23 When the organizer declares the campaign a success. -24 We must make sure the deadline for the campaign has passed and -25 The `totalPledged` surpassed the `target`. - - -### Pledger requests a reimbursement - -When a pledger requests a reimbursement 30. -We check that the expiration date has passed 32 and -that the goal wasn't achieved 33 . -Then we check that the amount that is reclaiming is the same we have stored in the Ledger 34. -We return the amount to the Pledger and remove it from the Ledger. - - -## Lessons learned - -- Explicit timeout -- Unrestricted open set of participants -- Choice restricted to timeouts and open participation - - -## Challenge - -Can you write a version of this contract that does the following: -a) Automatically decides if the campaign was successful or not (given the timeout). -b) Reimburses all the pledges automatically. - - -# Challenge: Translate a Solidity smart contract to Glow - -In order to learn something new, we normally try to learn it refers to something we already know. -That's why in this article, we are going to learn the Glow smart contract language -by studying an example in Solidity and then translating it to Glow - - -## The Ballot example - -Ballot.sol is the first program that loads when looking going to the Remix IDE - - pragma solidity >=0.7.0 <0.8.0; - contract Ballot { - -Declare a struct called Voter that is a complex type -consisting of the weight of a vote, a Boolean voted, -the address of the Voter, and an index called vote. - - struct Voter { - uint weight;// Weight is accumulated by delegation - bool voted; // if true, that person already voted - address delegate;// person delegated to - uint vote; // index of the voted proposal - } - -You have an address type called chairperson. - - address chairperson; - -You have a mapping where you map and address with a voter - - mapping(address => Voter) voters; - -You also create an array of proposals where each proposal is a complex type struct. - - Proposal[] proposals; - - struct Proposal { - // If you can limit the length to a certain number of bytes, - // always use one of bytes1 to bytes32 because they are much cheaper - bytes32 name; // short name (up to 32 bytes) - uint voteCount;// number of accumulated votes - } - -In the constructor Ballot, you initialize the chairperson as the message sender with weight 1. -You also create a list of proposals. - - constructor(bytes32[] memory proposalNames) { - chairperson = msg.sender; - voters[chairperson].weight = 1; - - for (uint i = 0; i < proposalNames.length; i++) { - // 'Proposal({...})' creates a temporary - // Proposal object and 'proposals.push(...)' - // appends it to the end of 'proposals'. - proposals.push(Proposal({ - name: proposalNames[i], - voteCount: 0 - })); - } - } - -Give the `Voter` the right to vote on this ballot. -It can only be called by the `Chairperson`. -Validate that the voters have not voted yet and assign voters a weight. - - function giveRightToVote(address voter) public { - require( - msg.sender == chairperson, - "Only chairperson can give right to vote." - ); - require( - !voters[voter].voted, - "The voter already voted." - ); - require(voters[voter].weight == 0, - "the voter already had voting rights"); - voters[voter].weight = 1; - } - -Then the delegate() function delegates your vote to the Voter $(to) after a couple of validations -such as the message sender is not the to address has not voted. - - function delegate(address to) public { - Voter storage sender = voters[msg.sender]; - require(!sender.voted, "You already voted."); - require(to != msg.sender, "Self-delegation is disallowed."); - - while (voters[to].delegate != address(0)) { - to = voters[to].delegate; - - // We found a loop in the Delegation, not allowed. - require(to != msg.sender, "Found loop in delegation."); - } - sender.voted = true; - sender.delegate = to; - Voter storage delegate_ = voters[to]; - if (delegate_.voted) { - // If the delegate already voted, - // directly add to the number of votes - proposals[delegate_.vote].voteCount += sender.weight; - } else { - // If the delegate did not vote yet, - // add to her weight. - delegate_.weight += sender.weight; - } - } - -Give your vote (including votes delegated to you) to proposal - - function vote(uint proposal) public { - Voter storage sender = voters[msg.sender]; - require(sender.weight != 0, "Has no right to vote"); - require(!sender.voted, "Already voted."); - sender.voted = true; - sender.vote = proposal; - - // If 'proposal' is out of the range of the array, - // this will throw automatically and revert all - // changes. - proposals[proposal].voteCount += sender.weight; - } - -Find which is the proposal with the most votes. - - function winningProposal() public view - returns (uint winningProposal_) - { - uint winningVoteCount = 0; - for (uint p = 0; p < proposals.length; p++) { - if (proposals[p].voteCount > winningVoteCount) { - winningVoteCount = proposals[p].voteCount; - winningProposal_ = p; - } - } - } - -Get the name of the winning proposal - - function winnerName() public view - returns (bytes32 winnerName_) - { - winnerName_ = proposals[winningProposal()].name; - } - } - - -## Visualization - -By reading the previous contract, we can identify the following actors and flow: -The `Chairman` creates a contract with a defined number of options. -Then gives names to each option. -And grants voting rights to voters. -A voter (Bob in this diagram) can delegate his vote to another voter. -Voters vote for one of the options by its number. -Then everyone can ask who is winning by the one that has more votes. - -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/ballot.png) - - -## How does the contract look in Glow? - -Now it is your turn. How does the previous smart contract look in Glow? - -Here are a few ideas on how you could get started with such a program: - -- One known proposal, one known voter -- Multiple known proposals, One known voter -- Multiple known proposals, Three known voters -- Multiple known proposals, Three known voters, with delegation -- Multiple known proposals, unknown voters, with delegation -- Multiple known proposals, unknown voters, with delegation, with giving voting rights From fa63ca5d925d063c4dfb631c1e5e406e1c005e23 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 09:57:12 +0000 Subject: [PATCH 51/99] Update 2021-02-25_11-00-00_explorer-en.md --- .../content/articles/en/2021-02-25_11-00-00_explorer-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md b/resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md index 51b8e5cc2..3465c247e 100644 --- a/resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md +++ b/resources/content/articles/en/2021-02-25_11-00-00_explorer-en.md @@ -4,5 +4,5 @@ description: EVM tools parent: 2021-02-25_11-00-tools order: 2 last_updated: "2020-12-17T09:00:00+01:00" -external_href: https://david.kevm.dev-mantis.iohkdev.io/ +external_href: https://explorer-evm.portal.dev.cardano.org/ --- From ff4c04416dc1c87224e2543f8fc09b0b3dff9e49 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:22:49 +0000 Subject: [PATCH 52/99] Rename 2021-02-03_07-00-00_glow000.md to 2021-02-03_07-00-00_getting-started.md --- ...07-00-00_glow000.md => 2021-02-03_07-00-00_getting-started.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow000.md => 2021-02-03_07-00-00_getting-started.md} (100%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow000.md b/resources/content/articles/en/2021-02-03_07-00-00_getting-started.md similarity index 100% rename from resources/content/articles/en/2021-02-03_07-00-00_glow000.md rename to resources/content/articles/en/2021-02-03_07-00-00_getting-started.md From 6feec7d59f1e120a60558d2f85106b8b7f3fa9eb Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:31:57 +0000 Subject: [PATCH 53/99] Rename 2021-02-03_07-00-00_getting-started.md to 2021-02-03_07-00-00_getting-started-en.md --- ...tting-started.md => 2021-02-03_07-00-00_getting-started-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{2021-02-03_07-00-00_getting-started.md => 2021-02-03_07-00-00_getting-started-en.md} (100%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_getting-started.md b/resources/content/articles/en/2021-02-03_07-00-00_getting-started-en.md similarity index 100% rename from resources/content/articles/en/2021-02-03_07-00-00_getting-started.md rename to resources/content/articles/en/2021-02-03_07-00-00_getting-started-en.md From 209d94b3359f54b8c7e7fccb333bafe1aa705f11 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:32:54 +0000 Subject: [PATCH 54/99] Update and rename 2021-02-03_07-00-00_glow010.md to 2021-02-03_07-00-00_glow-tutorial-en.md --- ...00-00_glow010.md => 2021-02-03_07-00-00_glow-tutorial-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow010.md => 2021-02-03_07-00-00_glow-tutorial-en.md} (93%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow010.md b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md similarity index 93% rename from resources/content/articles/en/2021-02-03_07-00-00_glow010.md rename to resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md index a78e5f34c..c10742264 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow010.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Glow tutorial description: Installation instructions order: 1 From 6fe0318ca3e9703682dc09eb612df26232179c99 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:37:11 +0000 Subject: [PATCH 55/99] Update and rename 2021-02-03_07-00-00_glow020.md to 2021-02-03_07-00-00_buy-signature-en.md --- ...0_glow020.md => 2021-02-03_07-00-00_buy-signature-en.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow020.md => 2021-02-03_07-00-00_buy-signature-en.md} (92%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow020.md b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md similarity index 92% rename from resources/content/articles/en/2021-02-03_07-00-00_glow020.md rename to resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md index 7690d7e09..53daf02fc 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow020.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md @@ -1,10 +1,10 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Buy Signature -description: Stuying the buy signature contract +description: Studying the buy signature contract order: 2 --- -# Buy Signature ([buy_sig.glow](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow))? +# [Buy Signature](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow) Let's imagine you want to have your testament notarized. What would you do? From 1a4edcea8afa0dce0f4e97c4b92b8e21e03eb238 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:38:35 +0000 Subject: [PATCH 56/99] Update and rename 2021-02-03_07-00-00_glow030.md to 2021-02-03_07-00-00_coin-flip-en.md --- ..._07-00-00_glow030.md => 2021-02-03_07-00-00_coin-flip-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow030.md => 2021-02-03_07-00-00_coin-flip-en.md} (98%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow030.md b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md similarity index 98% rename from resources/content/articles/en/2021-02-03_07-00-00_glow030.md rename to resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md index dd942f11e..d14836506 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow030.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Coin flip description: How can you flip a coin in Glow? order: 3 From d715c7e3ebc7e3c66c19396fcdafaf8019682114 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:39:54 +0000 Subject: [PATCH 57/99] Update and rename 2021-02-03_07-00-00_glow040.md to 2021-02-03_07-00-00_rock-paper-scissors-en.md --- ...ow040.md => 2021-02-03_07-00-00_rock-paper-scissors-en.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow040.md => 2021-02-03_07-00-00_rock-paper-scissors-en.md} (97%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow040.md b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md similarity index 97% rename from resources/content/articles/en/2021-02-03_07-00-00_glow040.md rename to resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md index ae5f45817..b9ab4c942 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow040.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md @@ -1,10 +1,10 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Rock, Paper Scissors description: Playing Rock, Paper, Scissors (rps-min.glow)? order: 4 --- -# Playing Rock, Paper, Scissors (rps-min.glow)? +# Playing Rock, Paper, Scissors (rps-min.glow) Rock, paper, scissors is the classic children's game where each child shows what they have chosen at the same time. The decision on who has won is based on the following rules: From 8356466b895c85b05e2f0f1952b64349100c06de Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:41:05 +0000 Subject: [PATCH 58/99] Update and rename 2021-02-03_07-00-00_glow050.md to 2021-02-03_07-00-00_deadman-switch-en.md --- ...0-00_glow050.md => 2021-02-03_07-00-00_deadman-switch-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow050.md => 2021-02-03_07-00-00_deadman-switch-en.md} (98%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow050.md b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md similarity index 98% rename from resources/content/articles/en/2021-02-03_07-00-00_glow050.md rename to resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md index 29fdac203..538a854fe 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow050.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Deadman switch description: How to create a deadman switch? order: 5 From d744410850f51d7ebb15b8b600fb94b95a089f6a Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:42:04 +0000 Subject: [PATCH 59/99] Update and rename 2021-02-03_07-00-00_glow060.md to 2021-02-03_07-00-00_simple-auction-en.md --- ...0-00_glow060.md => 2021-02-03_07-00-00_simple-auction-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow060.md => 2021-02-03_07-00-00_simple-auction-en.md} (98%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow060.md b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md similarity index 98% rename from resources/content/articles/en/2021-02-03_07-00-00_glow060.md rename to resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md index 678188932..f979a9e78 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow060.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Simple Auction description: How does the Simple Auction (auction.glow) contract work? order: 6 From bfca7bb83898c0764330e8daa16631c595f67a0e Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:43:01 +0000 Subject: [PATCH 60/99] Update and rename 2021-02-03_07-00-00_glow070.md to 2021-02-03_07-00-00_crowdfund-en.md --- ..._07-00-00_glow070.md => 2021-02-03_07-00-00_crowdfund-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow070.md => 2021-02-03_07-00-00_crowdfund-en.md} (98%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow070.md b/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md similarity index 98% rename from resources/content/articles/en/2021-02-03_07-00-00_glow070.md rename to resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md index b9ad3f7c7..ed05c69e7 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow070.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Crowdfund description: How does Crowdfunding.glow work? order: 7 From df1c2a31db794ff8dc988158f5db85dcf7178b2a Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:43:49 +0000 Subject: [PATCH 61/99] Update and rename 2021-02-03_07-00-00_glow080.md to 2021-02-03_07-00-00_challenge-en.md --- ..._07-00-00_glow080.md => 2021-02-03_07-00-00_challenge-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{2021-02-03_07-00-00_glow080.md => 2021-02-03_07-00-00_challenge-en.md} (99%) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow080.md b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md similarity index 99% rename from resources/content/articles/en/2021-02-03_07-00-00_glow080.md rename to resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md index 30127c526..8e38bd2c0 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow080.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow000 +parent: 2021-02-03_07-00-00_getting-started title: Challenge description: Translate a Solidity smart contract to Glow order: 8 From 1662166b3091fb31cc3a589d54ee91cbf6157408 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:45:03 +0000 Subject: [PATCH 62/99] Update 2021-02-03_07-00-00_buy-signature-en.md --- .../content/articles/en/2021-02-03_07-00-00_buy-signature-en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md index 53daf02fc..d5176af54 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md @@ -3,6 +3,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Buy Signature description: Studying the buy signature contract order: 2 +last_updated: "2021-02-25T09:00:00+01:00" --- # [Buy Signature](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow) From 0d8ebc64c8ca3bc6408db1872a791ae93783d8f1 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:45:28 +0000 Subject: [PATCH 63/99] Update 2021-02-03_07-00-00_challenge-en.md --- .../content/articles/en/2021-02-03_07-00-00_challenge-en.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md index 8e38bd2c0..c075a3a53 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md @@ -3,6 +3,8 @@ parent: 2021-02-03_07-00-00_getting-started title: Challenge description: Translate a Solidity smart contract to Glow order: 8 +last_updated: "2021-02-25T09:00:00+01:00" + --- # Challenge: Translate a Solidity smart contract to Glow From fdc3d5d6fabab15e6f23cb8ac9b2d2ea06a2b00a Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:45:49 +0000 Subject: [PATCH 64/99] Update 2021-02-03_07-00-00_coin-flip-en.md --- .../content/articles/en/2021-02-03_07-00-00_coin-flip-en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md index d14836506..56a893339 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md @@ -3,6 +3,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Coin flip description: How can you flip a coin in Glow? order: 3 +last_updated: "2021-02-25T09:00:00+01:00" --- # How can you flip a coin in Glow? (coinflip.glow) From 32ad12e652356761e3867e4d2b0d852c6ffec6c2 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:46:06 +0000 Subject: [PATCH 65/99] Update 2021-02-03_07-00-00_crowdfund-en.md --- .../content/articles/en/2021-02-03_07-00-00_crowdfund-en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md b/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md index ed05c69e7..da0b2c0b3 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md @@ -3,6 +3,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Crowdfund description: How does Crowdfunding.glow work? order: 7 +last_updated: "2021-02-25T09:00:00+01:00" --- # How does Crowdfunding.glow work? From 2503c6437614656419e84d3b775f582933720413 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:46:28 +0000 Subject: [PATCH 66/99] Update 2021-02-03_07-00-00_deadman-switch-en.md --- .../content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md index 538a854fe..8af4152c5 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md @@ -3,6 +3,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Deadman switch description: How to create a deadman switch? order: 5 +last_updated: "2021-02-25T09:00:00+01:00" --- # How to create a deadman switch? From 2913a1dd6e3467bced4bd941d285f6199929e0bd Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:47:08 +0000 Subject: [PATCH 67/99] Update 2021-02-03_07-00-00_getting-started-en.md --- .../articles/en/2021-02-03_07-00-00_getting-started-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_getting-started-en.md b/resources/content/articles/en/2021-02-03_07-00-00_getting-started-en.md index 424f8dd4b..1e85f1665 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_getting-started-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_getting-started-en.md @@ -1,5 +1,5 @@ --- -title: Get started +title: Getting started description: Study Glow using code examples order: 2 parent: 2020-05-04_06-00-00_glow From f4a80aaf4f9a1fbd004eaa3616ceb60190bb6f59 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:47:32 +0000 Subject: [PATCH 68/99] Update 2021-02-03_07-00-00_glow-tutorial-en.md --- .../content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md index c10742264..d8b76c663 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md @@ -3,6 +3,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Glow tutorial description: Installation instructions order: 1 +last_updated: "2021-02-25T09:00:00+01:00" --- # Glow Tutorial From 0fbc4d68015b2f0f8dd8fe6b8a0b7bb627e169f9 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:47:52 +0000 Subject: [PATCH 69/99] Update 2021-02-03_07-00-00_rock-paper-scissors-en.md --- .../articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md index b9ab4c942..c829abeee 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md @@ -3,6 +3,8 @@ parent: 2021-02-03_07-00-00_getting-started title: Rock, Paper Scissors description: Playing Rock, Paper, Scissors (rps-min.glow)? order: 4 +last_updated: "2021-02-25T09:00:00+01:00" + --- # Playing Rock, Paper, Scissors (rps-min.glow) From 733badbfba23aafdcc97ad3978862b0a57302508 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 10:48:09 +0000 Subject: [PATCH 70/99] Update 2021-02-03_07-00-00_simple-auction-en.md --- .../content/articles/en/2021-02-03_07-00-00_simple-auction-en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md index f979a9e78..64ad89783 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md @@ -3,6 +3,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Simple Auction description: How does the Simple Auction (auction.glow) contract work? order: 6 +last_updated: "2021-02-25T09:00:00+01:00" --- # How does the Simple Auction (auction.glow) contract work? From 38684ba124fac27991960ec0175e902bc4a9c24a Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 11:16:32 +0000 Subject: [PATCH 71/99] Update 2021-02-03_07-00-00_buy-signature-en.md --- .../content/articles/en/2021-02-03_07-00-00_buy-signature-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md index d5176af54..4d8f0d58a 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md @@ -31,7 +31,7 @@ This is the interaction that the `buy_sig.glow` contract represents. ## Visualizing the Buyer and Seller interactions -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/buy_sig.png) +![img](https://ucarecdn.com/0d9b3724-ed89-4414-ad67-48bf0de1a94f/buy_sig.png) ## Glow code From 911a433fcf5a540c1cb2d3dc25d29a3a733cfd59 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 11:18:15 +0000 Subject: [PATCH 72/99] Update 2021-02-03_07-00-00_coin-flip-en.md --- .../content/articles/en/2021-02-03_07-00-00_coin-flip-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md index 56a893339..a7343ad39 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md @@ -24,7 +24,7 @@ Both outcomes have a 50 / 50 chance of happening. ## Sequence diagram -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/coinflip.png) +![img](https://ucarecdn.com/ffc7e8a4-0c70-4c2e-869f-bc77a378ef0f/coinflip.png) ## Glow code From 4a091519d9fa99c5a0d1181da0a218e2323ae7ff Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 11:20:43 +0000 Subject: [PATCH 73/99] Update 2021-02-03_07-00-00_rock-paper-scissors-en.md --- .../articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md index c829abeee..dad741c9e 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md @@ -22,7 +22,7 @@ How does a player communicate their choice to the blockchain during the game? ## Visualization -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png) +![img](https://ucarecdn.com/d5dde20b-63c6-4cd7-b774-6694f4080cc8/rpsmin.png) ## Glow code From 12224813c787fb73425f8c52dbc1da96f2d464cb Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 11:22:21 +0000 Subject: [PATCH 74/99] Update 2021-02-03_07-00-00_deadman-switch-en.md --- .../articles/en/2021-02-03_07-00-00_deadman-switch-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md index 8af4152c5..4926fc298 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md @@ -16,7 +16,7 @@ In this contract, we are going to see how your uncle implemented that contract i ## Visualization -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png) +![img](https://ucarecdn.com/8b0ba880-443f-4b43-991d-ed5ac2dd2350/deadmanswitch.png) ## Glow Code From 76d04b944d558cd6c1cf133ab66eb3bc569e685a Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 11:23:59 +0000 Subject: [PATCH 75/99] Update 2021-02-03_07-00-00_simple-auction-en.md --- .../articles/en/2021-02-03_07-00-00_simple-auction-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md index 64ad89783..85286f787 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md @@ -14,7 +14,7 @@ They get their money back when they are outbid. ## Visualization -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/auction.png) +![img](https://ucarecdn.com/ba79de1d-e526-466f-9d4f-b1747c7ad3b8/auction.png) ## Glow code From b54985640cb9dbc491519d79c5ce9ed6fbae1ebe Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 11:25:29 +0000 Subject: [PATCH 76/99] Update 2021-02-03_07-00-00_challenge-en.md --- .../content/articles/en/2021-02-03_07-00-00_challenge-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md index c075a3a53..d7ce53237 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md @@ -163,7 +163,7 @@ A voter (Bob in this diagram) can delegate his vote to another voter. Voters vote for one of the options by its number. Then everyone can ask who is winning by the one that has more votes. -![img](../article-images/2021-02-03_07-00-00_learning-glow-by-example/ballot.png) +![img](https://ucarecdn.com/5dd5c388-7578-45a9-aea9-644d5ccf332c/ballot.png) ## How does the contract look in Glow? From 32515c769e7a4953960bf10ac0b9b74ae7461a2b Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:16:26 +0000 Subject: [PATCH 77/99] new Glow install and network files --- resources/content/articles/en/glow-install.md | 21 +++ .../content/articles/en/glow-test-network.md | 174 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 resources/content/articles/en/glow-install.md create mode 100644 resources/content/articles/en/glow-test-network.md diff --git a/resources/content/articles/en/glow-install.md b/resources/content/articles/en/glow-install.md new file mode 100644 index 000000000..8bebbe895 --- /dev/null +++ b/resources/content/articles/en/glow-install.md @@ -0,0 +1,21 @@ +--- +title: Installing Glow +description: +parent: +order: 1 +last_updated: "2020-05-01T09:00:00+01:00" +--- +## Installing Glow + +The first step is to install Glow so that you can get started. Glow can be installed on either Linux or MacOs. You can run the installation inside a virtual machine and for extra security we recommend that you use [Qubes OS](https://www.qubes-os.org/). + +To install Glow, follow these steps: +1. Open a terminal window (or any application on your system that allows you to enter shell commands). +2. Type the following command line: +`curl -L https://glow-lang.org/install/glow-install | sh` + +This installation script first installs the [Nix](https://nixos.org/) package manager, which may require you to manually type yes, or y and/or type the administrator password to authorize parts of the installation. If you weren’t using Nix before, you may have to start a new shell for the PATH to be set up correctly and be able to run glow. + +Note: If you use Linux or macOS on x86_64, all the binary packages for the software are cached, and the installation should only take a few minutes, depending on the speed of your internet connection. This software may require over 2GB of memory, so please ensure that you have enough available space on disk. If you use another platform, your computer may recompile code from source, so you should let it run overnight. + +We plan to release a Docker image soon, so please check back for updates. \ No newline at end of file diff --git a/resources/content/articles/en/glow-test-network.md b/resources/content/articles/en/glow-test-network.md new file mode 100644 index 000000000..e33c69272 --- /dev/null +++ b/resources/content/articles/en/glow-test-network.md @@ -0,0 +1,174 @@ +--- +title: Setting up the Test Network +description: Setting up the Test Network +parent: 2021-02-03_07-00-00_getting-started +order: 3 +last_updated: "2021-02-25T09:00:00+01:00" +--- +## Setting up the Test Network + +By default, Glow will use the Cardano EVM Devnet (“ced”)—a public network on which you can interact with other users. You may experience a short delay of a minute or so when confirming each step of the interaction. + +For faster local-only tests with confirmations in a couple of seconds, you can instead run your own private Ethereum test network (“pet”) on your computer with these instructions. You should add the flags --evm-network pet to your invocations of Glow, as follows: + +`git clone https://github.com/fare/gerbil-ethereum.git +cd gerbil-ethereum +./scripts/run-ethereum-test-net.ss` + +### Creating Keys +Each participant must first generate their own identity on their own machine, with their own secret key, as follows: + +Alice: +`glow generate-identity --nickname Alice` + +Bob: +`glow generate-identity --nickname Bob` + +### Sharing Contact Information +After creating your key, you must share it with the other participant in the interaction (for example, using a chat application such as Slack). + +First, each participant lists their address using: +`glow list-identities` + +The listed addresses will appear in the following format (these are examples): +`Alice [ 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 ]` +`Bob [ 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD ]` + +Each participant then uses a copy and paste function to share their address with the other participant, who will register it as follows: +Alice replaces the address with Bob’s actual address, as follows: +`address=0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD` +`glow add-contact --nickname Bob --address ${address}` + +Bob replaces the address with Alice’s actual address, as follows: +`address=0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1` +`glow add-contact --nickname Alice --address ${address}` + +### Getting Tokens from the Faucet: +As your address is a new address it does not have any tokens to spend, or to use to pay for gas. To get some tokens for your address you can use the test network’s faucet, as follows: + +Alice runs: +`glow faucet --to Alice --evm-network pet` + +Bob runs: +`glow faucet --to Bob --evm-network pet` + +(If you are using your own private Ethereum test network, the two commands above and every command below (with the exception of the digest command) are where you must add the flags --evm-network pet to your invocations of glow.) + +### Configuring the Interactions +This section outlines how you should configure the contract interactions of Alice and Bob. + +#### Setting up Alice’s Interaction +One of the two participants writes a document for the other to sign. For example, Alice prepares the following document and sends it to Bob for review: + +`echo “Bob sells BLAH to Alice” > document.txt` + +When both agree on the document, they should each compute its digest with: + +`glow digest document.txt` + +Now, Alice can sign the interaction. In the scenario where you are running the interactions on the same machine, you should specify a database so the two users will not conflict with each other’s data; the extra database specification is not necessary if the users are running on different machines. + +`glow start-interaction --database run/Alice --evm-network pet` + +The CLI will then prompt Alice to select an application, choose which identity to use for the interaction, which role they will play in it, assign addresses to roles of the other identities, enter the interaction parameters, and finally, print the interaction agreement for Alice to send to Bob, so that he can configure his side of the interaction with the same parameters. + +Here is an example of what the setup should look like from Alice’s side: + +Choose application: +1) coin_flip +2) buy_sig +3) rps_simple +Enter number +> 2 + +Choose your identity: +1) Alice - 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 +Enter number +> 1 + +Choose your role: +1) Buyer +2) Seller +Enter number +> 1 + +Assign roles +Select address for Seller: +1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD +Enter number +> 1 + +Define parameters +Enter digest +> 0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20 +Enter price +> 1000 + +Max initial block [ Current block number is 350 ] +> 500 + +One line command for other participants to generate the same agreement: +./glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' +Setup interaction (Bob) + +Bob has a lot less steps since the agreement contains all of the parameters. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s when running both participants on the same machine. + +glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B + +Choose your identity: +1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD +Enter number +> 1 + +Choose your role: +1) Buyer +2) Seller +Enter number +> 2 + +Start interaction (Alice) + +After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything specified in the agreement. + +Send the handshake below to the other participant: +{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} + +Run interaction (Alice + Bob) + +All Bob has left to do is paste the handshake when prompted and the runtime will handle everything from there. First by generating a signature of the digest and then publishing it on-chain. Alice’s runtime will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. + +The last thing the runtime does is print all the variables that were bound during execution of the contract, with the signature being purchased highlighted for both participants. + +#### Setting up Bob's Interaction +Bob’s interaction does not require as many steps since the agreement contains all of the parameters already. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s, when running both participants on the same machine. + +glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B + +Choose your identity: +1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD +Enter number +> 1 + +Choose your role: +1) Buyer +2) Seller +Enter number +> 2 + +#### Starting Alice’s Interaction +After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything that is specified in the agreement. + +Send the handshake below to the other participant: +{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} + +#### Running the Alice and Bob Interaction +All Bob has left to do is paste the handshake when he is prompted to do so and the runtime component will handle everything from there. The first thing that will happen is that a signature of the digest is generated and then published on-chain. Alice’s runtime component will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. + +The last thing the runtime component does is to print all the variables that were bound during execution of the contract, with the signature that is being purchased highlighted for both participants. + + + + + + + From 432e3726082e1f858d6cf77892d0e1486b87eb7f Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:18:01 +0000 Subject: [PATCH 78/99] Update glow-install.md edited front matter --- resources/content/articles/en/glow-install.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/content/articles/en/glow-install.md b/resources/content/articles/en/glow-install.md index 8bebbe895..d33cdd81d 100644 --- a/resources/content/articles/en/glow-install.md +++ b/resources/content/articles/en/glow-install.md @@ -1,9 +1,9 @@ --- title: Installing Glow -description: -parent: -order: 1 -last_updated: "2020-05-01T09:00:00+01:00" +description: Installing Glow +parent: 2021-02-03_07-00-00_getting-started +order: 3 +last_updated: "2021-02-25T09:00:00+01:00" --- ## Installing Glow @@ -18,4 +18,4 @@ This installation script first installs the [Nix](https://nixos.org/) package ma Note: If you use Linux or macOS on x86_64, all the binary packages for the software are cached, and the installation should only take a few minutes, depending on the speed of your internet connection. This software may require over 2GB of memory, so please ensure that you have enough available space on disk. If you use another platform, your computer may recompile code from source, so you should let it run overnight. -We plan to release a Docker image soon, so please check back for updates. \ No newline at end of file +We plan to release a Docker image soon, so please check back for updates. From b91f8380de13f5fb5e1fc121271d53c941204b35 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:27:30 +0000 Subject: [PATCH 79/99] Update 2021-02-03_07-00-00_simple-auction-en.md --- .../articles/en/2021-02-03_07-00-00_simple-auction-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md index 85286f787..769d1304f 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_getting-started +parent: 2021-02-03_07-00-00_glow-tutorial-en.md title: Simple Auction description: How does the Simple Auction (auction.glow) contract work? order: 6 From ace5237cfabb6adbf12568da5d7b2fa77f622e8f Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:31:18 +0000 Subject: [PATCH 80/99] Update 2021-02-03_07-00-00_glow-tutorial-en.md removing install para --- .../en/2021-02-03_07-00-00_glow-tutorial-en.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md index d8b76c663..398f329a7 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md @@ -12,13 +12,3 @@ Glow is a language for developing secure decentralized apps (DApps) that can run In this tutorial, we analyze the sample programs that are provided in the Glow distribution to learn how they work, and how could they can be applied to smart contract and DApp development. - -## Installation - -Currently the most reliable way to install Glow is from source with: - -'''sh -curl -L https://glow-lang.org/install/glow-install | sh -''' - -For more information: [INSTALL.md](https://gitlab.com/mukn/glow/-/blob/master/INSTALL.md) From f6659e88751a272ba7c6e4dbd2d6d3d0086388de Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:45:21 +0000 Subject: [PATCH 81/99] Update 2021-02-03_07-00-00_simple-auction-en.md --- .../articles/en/2021-02-03_07-00-00_simple-auction-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md index 769d1304f..8f7c8d89d 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md @@ -1,5 +1,5 @@ --- -parent: 2021-02-03_07-00-00_glow-tutorial-en.md +parent: 2021-02-03_07-00-00_glow-tutorial title: Simple Auction description: How does the Simple Auction (auction.glow) contract work? order: 6 From 6f770522373d93c5d3b9cc3dddcb2380b7974334 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:49:05 +0000 Subject: [PATCH 82/99] Rename glow-install.md to 2021-02-25_07-00-00_glow-install-en.md --- .../{glow-install.md => 2021-02-25_07-00-00_glow-install-en.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/content/articles/en/{glow-install.md => 2021-02-25_07-00-00_glow-install-en.md} (100%) diff --git a/resources/content/articles/en/glow-install.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md similarity index 100% rename from resources/content/articles/en/glow-install.md rename to resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md From c0718237c9fca25e26f3e059edaac5974c15ec08 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:02:50 +0000 Subject: [PATCH 83/99] Update 2021-02-25_07-00-00_glow-install-en.md --- .../content/articles/en/2021-02-25_07-00-00_glow-install-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md index d33cdd81d..d00ca2ba0 100644 --- a/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md +++ b/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md @@ -2,7 +2,7 @@ title: Installing Glow description: Installing Glow parent: 2021-02-03_07-00-00_getting-started -order: 3 +order: 1 last_updated: "2021-02-25T09:00:00+01:00" --- ## Installing Glow From 56fefe1dc58a70edd431e4b13a07386884c57612 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:04:14 +0000 Subject: [PATCH 84/99] Update and rename glow-test-network.md to 2021-02-25_07-00-00_glow-test-network-en.md --- ...t-network.md => 2021-02-25_07-00-00_glow-test-network-en.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename resources/content/articles/en/{glow-test-network.md => 2021-02-25_07-00-00_glow-test-network-en.md} (98%) diff --git a/resources/content/articles/en/glow-test-network.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md similarity index 98% rename from resources/content/articles/en/glow-test-network.md rename to resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md index e33c69272..78e098710 100644 --- a/resources/content/articles/en/glow-test-network.md +++ b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md @@ -2,7 +2,7 @@ title: Setting up the Test Network description: Setting up the Test Network parent: 2021-02-03_07-00-00_getting-started -order: 3 +order: 2 last_updated: "2021-02-25T09:00:00+01:00" --- ## Setting up the Test Network From 13ec1c9857e24248665d026da183a54b190e656b Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:04:35 +0000 Subject: [PATCH 85/99] Update 2021-02-03_07-00-00_glow-tutorial-en.md --- .../content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md index 398f329a7..8cde09373 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md @@ -2,7 +2,7 @@ parent: 2021-02-03_07-00-00_getting-started title: Glow tutorial description: Installation instructions -order: 1 +order: 3 last_updated: "2021-02-25T09:00:00+01:00" --- From 8ca3e870f05f4a45f64cd48dba0b231229b91654 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:05:05 +0000 Subject: [PATCH 86/99] Delete 2021-02-03_07-00-00_simple-auction-en.md --- .../2021-02-03_07-00-00_simple-auction-en.md | 85 ------------------- 1 file changed, 85 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md b/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md deleted file mode 100644 index 8f7c8d89d..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_simple-auction-en.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_glow-tutorial -title: Simple Auction -description: How does the Simple Auction (auction.glow) contract work? -order: 6 -last_updated: "2021-02-25T09:00:00+01:00" ---- -# How does the Simple Auction (auction.glow) contract work? - -Imagine an auction where each one of the bidders tries to outbid the previous bidder. -However, in a blockchain auction, each bidder has to declare the money first to become the top bidder. -They get their money back when they are outbid. - - -## Visualization - -![img](https://ucarecdn.com/ba79de1d-e526-466f-9d4f-b1747c7ad3b8/auction.png) - - -## Glow code - - 1 #lang glow - 2 data Action = Bid(TokenAmount) | BuyItNow | Close; - 3 - 4 @interaction([Seller]) - 5 let simpleAuction = (goods : Assets, expirationTime : Timestamp, buyItNowPrice: TokenAmount) => { - 6 require! Assets.is_positive(goods); - 7 require! expirationTime > currentTime(); - 8 deposit! Seller -> goods; - 9 - 10 @interaction([Seller, CurrentBidder]) - 11 let rec auction = (currentBid) => { - 12 assert! @deposited == goods + currentBid; - 13 choice { - 14 | ForAllParticipant (NewBidder) { - 15 @NewBidder bid = Bid(input(["Enter next bid"], TokenAmout)); - 16 publish! NewBidder -> bid ; deposit! NewBidder -> bid; - 17 @NewBidder assume! @value(goods) > @value(bid); - 18 require! currentTime() < expirationTime; - 19 require! bid > currentBid; - 20 require! bid < buyItNowPrice; - 21 withdraw! CurrentBidder <- currentBid; - 22 @interaction([Seller, NewBidder]) auction(bid); - 23 | ForAllParticipant (NewBidder) { - 24 publish! NewBidder -> BuyItNow ; deposit! NewBidder -> buyItNowPrice; - 25 require! currentTime() < expirationTime; - 26 withdraw! NewBidder <- goods; - 27 withdraw! CurrentBidder <- currentBid; - 28 withdraw! Seller <- buyItNowPrice; - 29 | @_ { publish! Close; } => - 30 require! currentTime() >= expirationTime; - 31 withdraw! Seller <- currentBid; - 32 withdraw! CurrentBidder <- goods; - 33 }; - 34 @interaction([Seller, Seller]) auction(0); - 35 } - -- 2 Declares the possible commands that could be performed on this contract -- 4 Only the Seller can create an auction -- **5:** In order to create an auction, a Seller must provide: - -The `Goods` that could be anything that can be represented as an asset, -an `expirationTime` at which point the auction is over and -a price at which to buy it immediately `buyItNowPrice`. - -- 8 The Seller must deposit the goods in the smart contract. This could, for example, a photograph. -- 34 The real auction begins at 0, and the "first bidder" is the Seller himself. -- 10 The real auction is an interaction between the Seller and the Current bidder. -- 11 This function is recursive, so it can call itself. -- 12 A sanity check, let's make sure that the amount deposited to the contract is the goods plus the current bidder. -- 14 This is key in this contract; anyone that bids may become a participant. -- 15 The contract as the new participant for their bid. -- 16 The new bid should be public and it's deposited into the contract. -- 19 The new bid must be bigger than the current one in order to replace it. -- 21 The previous highest bidder gets its money back since it has been replaced by the new bid. -- 22 Now the auction may continue, recursively, with a new highest bidder. -- 23 If the new bidder, reaches the *buy it now* price. Then the auction is settled right now. -- 29 If the expiration time is reached, then the auction is settled. - - -## Lessons learned - -- Recursive function definitions -- How to involve participants that are not known beforehand. -- How to use an expiration date From 7fe0a8a80b0c988c4c44f27ad9163791891ed433 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:05:21 +0000 Subject: [PATCH 87/99] Delete 2021-02-03_07-00-00_buy-signature-en.md --- .../2021-02-03_07-00-00_buy-signature-en.md | 70 ------------------- 1 file changed, 70 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md b/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md deleted file mode 100644 index 4d8f0d58a..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_buy-signature-en.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Buy Signature -description: Studying the buy signature contract -order: 2 -last_updated: "2021-02-25T09:00:00+01:00" ---- -# [Buy Signature](https://gitlab.com/mukn/glow/-/blob/master/future/buy_sig.glow) - -Let's imagine you want to have your testament notarized. What would you do? - -> You first write your testament -> You pay a notary to stamp it -> You store a copy for future reference - -If you think about it, there are many interactions in the world that follow that same process: - -- When your diploma is certified by your University. -- When you renew your driver's license, there is no test, just a renewal stamp. - -We could generalize the process as: - -> A buyer (you in this case) -> Pays a seller -> Takes something, or better yet, a representation of the item (a digest) to a seller. -> The seller can now sign the digest. -> All parties can see that the digest was signed. - -This is the interaction that the `buy_sig.glow` contract represents. - - -## Visualizing the Buyer and Seller interactions - -![img](https://ucarecdn.com/0d9b3724-ed89-4414-ad67-48bf0de1a94f/buy_sig.png) - - -## Glow code - - 1 #lang glow - 2 @interaction([Buyer, Seller]) - 3 let payForSignature = (digest : Digest, price : Assets) => { - 4 deposit! Buyer -> price; - 5 @verifiably!(Seller) let signature = sign(digest); - 6 publish! Seller -> signature; - 7 verify! signature; - 8 withdraw! Seller <- price; - 9 } - -2. Buyer and seller have agreed to the terms of this sale. They both know what the signature is about, and they want to conduct this sale. -3. The digest of the message to sign is a parameter of the interaction, as is the convened price. -4. The buyer deposits the money according to the price. -5. The seller signs, but it is private only to the seller. -6. The signature is made public for everyone to see. -7. The signature is verified by everyone in a way that the contract enforces. -8. Finally, the money is transferred to the seller. - -There are several things to note: - -1. The code looks a lot like the sequence diagram we created before. -2. The lines of code with @Seller annotation are private. -3. The language itself takes care of requirements. If the buyer never deposits, then the seller never will be able to sign. - - -## Lessons learned - -- Identify the participants of a contract with `@interaction` - -When an instruction is annotated with the participant's name, that value is private for the participant. Like `@verifiably!(Seller)` - -- There are clear instructions for `deposit!` and `withdraw!` From b7b3ebd5360618fa3864cc4c5ae8cd1be4fedaa5 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:05:35 +0000 Subject: [PATCH 88/99] Delete 2021-02-03_07-00-00_coin-flip-en.md --- .../en/2021-02-03_07-00-00_coin-flip-en.md | 78 ------------------- 1 file changed, 78 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md b/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md deleted file mode 100644 index a7343ad39..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_coin-flip-en.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Coin flip -description: How can you flip a coin in Glow? -order: 3 -last_updated: "2021-02-25T09:00:00+01:00" ---- -# How can you flip a coin in Glow? (coinflip.glow) - -Flipping a coin is a game as old as, well, coins. -Alice throws the coin *in the air*, -Bob calls whatever he thinks is going to be the outcome. -The loser pays the winner the agreed amount. - -However, on blockchain, there is no such thing as *in the air*. -So, how can we have something random that has a 50 / 50 chance for Alice? - -For example, Alice flips her coin. -Bob flips his coin -And then Alice wins if both coins match. -Or Bob wins if the coins are different. -Both outcomes have a 50 / 50 chance of happening. - - -## Sequence diagram - -![img](https://ucarecdn.com/ffc7e8a4-0c70-4c2e-869f-bc77a378ef0f/coinflip.png) - - -## Glow code - -The following Glow code exmaple represents the previous interaction: - - 1 #lang glow - 2 @interaction([A, B]) - 3 let coinFlip = (wagerAmount) => { - 4 @A assert! canReach(A_wins); - 5 @A let randA = randomUInt256(); - 6 @verifiably!(A) let commitment = digest(randA); - 7 publish! A -> commitment; deposit! A -> wagerAmount; - 8 @B assert! canReach(B_wins); - 9 @B let randB = randomUInt256(); - 10 publish! B -> randB; deposit! B -> wagerAmount; - 11 publish! A -> randA; - 12 verify! commitment; - 13 if (((randA ^^^ randB) &&& 1) == 0) { - 14 A_wins: withdraw! A <- 2*wagerAmount - 15 } else { - 16 B_wins: withdraw! B <- 2*wagerAmount - 17 } - 18 }; - -1. Every Glow program starts with the #lang glow identification -2. We know that two actors, A and B (Alice and Bob), are going to participate in this contract -3. coinFlip needs to know the amount each player is going to bet to get started. -4. Alice needs to be assured that there is a state where she can win. Ie. `assert!` makes sure that the program can reach the label `A_wins` -5. Alice draws random numbers between 0 and 2256. Approx. 78 decimal digits. -6. Alice stores in the commitment value the digest of the random number she generated. -7. She publishes her commitment on the blockchain and deposits her wager. - -Now it is Bob's turn: - -8. Bob makes sure that it is possible to get to the `B_wins` label to know that he can win. -9. Bob flips a coin. i.e., draws a random number between 0 and 2256. -10. Bob publishes the coin that he flipped and deposits his wager. -11. Alice publishes the coin that she threw. -12. We `verify!` that the commitment matches the coin that she threw. -13. By doing a bitwise XOR of the random numbers thrown by Alice and Bob, we find that they match -14. Alice wins and withdraws two times the wager -15. However, If the `xor` doesn't match, Bob wins -16. In addition, Bob gets double the bet. - - -## Lessons learned - -- You can generate random numbers with `randomUInt256` -- You can `assert!` you can reach a label such as `A_wins:` -- There are bitwise operations with like `^^^` and `&&&` From 8ab4ff3a8af31a1eae2900d19b2c19ca6cd7bcbe Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:06:02 +0000 Subject: [PATCH 89/99] Update 2020-11-25_09-00-00_overview-en.md added link for Glow --- .../content/articles/en/2020-11-25_09-00-00_overview-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md b/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md index f8f3268c0..69bdc7613 100644 --- a/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md +++ b/resources/content/articles/en/2020-11-25_09-00-00_overview-en.md @@ -8,7 +8,7 @@ hasNoChildContent: true --- ## Overview -Glow is a new domain specific language (DSL) for developing decentralized applications (DApps) on blockchain. With Glow, you can write secure DApps and be assured that your smart contracts can run safely in an adversarial environment. Glow is the brainchild of [MuKn](https://mukn.io), a valued community partner within the Cardano ecosystem. +[Glow](https://glow-lang.org/) is a new domain specific language (DSL) for developing decentralized applications (DApps) on blockchain. With Glow, you can write secure DApps and be assured that your smart contracts can run safely in an adversarial environment. Glow is the brainchild of [MuKn](https://mukn.io), a valued community partner within the Cardano ecosystem. Glow is a language to develop not just a smart contract, but an entire DApp itself, which also includes client code and formal proofs. It is backed by formal methods that are intrinsically built into the language and its actual implementation. It is this inherent correctness of the language that means the code will perform as expected and the DApp will behave as users want (so users do not have their transactions blocked or their assets locked). From 4ef2a76e799d818a59e161a9dbb21099eb8eef02 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:06:05 +0000 Subject: [PATCH 90/99] Delete 2021-02-25_07-00-00_glow-test-network-en.md --- ...021-02-25_07-00-00_glow-test-network-en.md | 174 ------------------ 1 file changed, 174 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md diff --git a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md deleted file mode 100644 index 78e098710..000000000 --- a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -title: Setting up the Test Network -description: Setting up the Test Network -parent: 2021-02-03_07-00-00_getting-started -order: 2 -last_updated: "2021-02-25T09:00:00+01:00" ---- -## Setting up the Test Network - -By default, Glow will use the Cardano EVM Devnet (“ced”)—a public network on which you can interact with other users. You may experience a short delay of a minute or so when confirming each step of the interaction. - -For faster local-only tests with confirmations in a couple of seconds, you can instead run your own private Ethereum test network (“pet”) on your computer with these instructions. You should add the flags --evm-network pet to your invocations of Glow, as follows: - -`git clone https://github.com/fare/gerbil-ethereum.git -cd gerbil-ethereum -./scripts/run-ethereum-test-net.ss` - -### Creating Keys -Each participant must first generate their own identity on their own machine, with their own secret key, as follows: - -Alice: -`glow generate-identity --nickname Alice` - -Bob: -`glow generate-identity --nickname Bob` - -### Sharing Contact Information -After creating your key, you must share it with the other participant in the interaction (for example, using a chat application such as Slack). - -First, each participant lists their address using: -`glow list-identities` - -The listed addresses will appear in the following format (these are examples): -`Alice [ 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 ]` -`Bob [ 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD ]` - -Each participant then uses a copy and paste function to share their address with the other participant, who will register it as follows: -Alice replaces the address with Bob’s actual address, as follows: -`address=0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD` -`glow add-contact --nickname Bob --address ${address}` - -Bob replaces the address with Alice’s actual address, as follows: -`address=0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1` -`glow add-contact --nickname Alice --address ${address}` - -### Getting Tokens from the Faucet: -As your address is a new address it does not have any tokens to spend, or to use to pay for gas. To get some tokens for your address you can use the test network’s faucet, as follows: - -Alice runs: -`glow faucet --to Alice --evm-network pet` - -Bob runs: -`glow faucet --to Bob --evm-network pet` - -(If you are using your own private Ethereum test network, the two commands above and every command below (with the exception of the digest command) are where you must add the flags --evm-network pet to your invocations of glow.) - -### Configuring the Interactions -This section outlines how you should configure the contract interactions of Alice and Bob. - -#### Setting up Alice’s Interaction -One of the two participants writes a document for the other to sign. For example, Alice prepares the following document and sends it to Bob for review: - -`echo “Bob sells BLAH to Alice” > document.txt` - -When both agree on the document, they should each compute its digest with: - -`glow digest document.txt` - -Now, Alice can sign the interaction. In the scenario where you are running the interactions on the same machine, you should specify a database so the two users will not conflict with each other’s data; the extra database specification is not necessary if the users are running on different machines. - -`glow start-interaction --database run/Alice --evm-network pet` - -The CLI will then prompt Alice to select an application, choose which identity to use for the interaction, which role they will play in it, assign addresses to roles of the other identities, enter the interaction parameters, and finally, print the interaction agreement for Alice to send to Bob, so that he can configure his side of the interaction with the same parameters. - -Here is an example of what the setup should look like from Alice’s side: - -Choose application: -1) coin_flip -2) buy_sig -3) rps_simple -Enter number -> 2 - -Choose your identity: -1) Alice - 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 -Enter number -> 1 - -Choose your role: -1) Buyer -2) Seller -Enter number -> 1 - -Assign roles -Select address for Seller: -1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD -Enter number -> 1 - -Define parameters -Enter digest -> 0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20 -Enter price -> 1000 - -Max initial block [ Current block number is 350 ] -> 500 - -One line command for other participants to generate the same agreement: -./glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' -Setup interaction (Bob) - -Bob has a lot less steps since the agreement contains all of the parameters. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s when running both participants on the same machine. - -glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B - -Choose your identity: -1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD -Enter number -> 1 - -Choose your role: -1) Buyer -2) Seller -Enter number -> 2 - -Start interaction (Alice) - -After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything specified in the agreement. - -Send the handshake below to the other participant: -{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} - -Run interaction (Alice + Bob) - -All Bob has left to do is paste the handshake when prompted and the runtime will handle everything from there. First by generating a signature of the digest and then publishing it on-chain. Alice’s runtime will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. - -The last thing the runtime does is print all the variables that were bound during execution of the contract, with the signature being purchased highlighted for both participants. - -#### Setting up Bob's Interaction -Bob’s interaction does not require as many steps since the agreement contains all of the parameters already. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s, when running both participants on the same machine. - -glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B - -Choose your identity: -1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD -Enter number -> 1 - -Choose your role: -1) Buyer -2) Seller -Enter number -> 2 - -#### Starting Alice’s Interaction -After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything that is specified in the agreement. - -Send the handshake below to the other participant: -{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} - -#### Running the Alice and Bob Interaction -All Bob has left to do is paste the handshake when he is prompted to do so and the runtime component will handle everything from there. The first thing that will happen is that a signature of the digest is generated and then published on-chain. Alice’s runtime component will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. - -The last thing the runtime component does is to print all the variables that were bound during execution of the contract, with the signature that is being purchased highlighted for both participants. - - - - - - - From 35ca5a6a7a154f09824a542b4c3a7cfa367e5f4b Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:06:28 +0000 Subject: [PATCH 91/99] Delete 2021-02-03_07-00-00_rock-paper-scissors-en.md --- ...1-02-03_07-00-00_rock-paper-scissors-en.md | 89 ------------------- 1 file changed, 89 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md b/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md deleted file mode 100644 index dad741c9e..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_rock-paper-scissors-en.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Rock, Paper Scissors -description: Playing Rock, Paper, Scissors (rps-min.glow)? -order: 4 -last_updated: "2021-02-25T09:00:00+01:00" - ---- -# Playing Rock, Paper, Scissors (rps-min.glow) - -Rock, paper, scissors is the classic children's game where each child shows what they have chosen at the same time. -The decision on who has won is based on the following rules: - -- Both selected the same: Draw -- Rock beats scissors -- Paper beats rock -- Scissors beats paper - -How con you code this in Glow if there is no *at the same time*. -How does a player communicate their choice to the blockchain during the game? - - -## Visualization - -![img](https://ucarecdn.com/d5dde20b-63c6-4cd7-b774-6694f4080cc8/rpsmin.png) - - -## Glow code - - 1 #lang glow - 2 data Hand = | Rock | Paper | Scissors; - 3 data Outcome = | B_Wins | Draw | A_Wins; - 4 let winner = (handA : Hand, handB : Hand) : Outcome => { - 5 Outcome.ofNat((Hand.toNat(handA) + (4 - Hand.toNat(handB))) % 3) } - 6 - 7 @interaction([A, B]) - 8 let rockPaperScissors = (wagerAmount) => { - 9 @A assert! canReach(end, end.outcome == A_Wins); - 10 @A let handA = Hand.input("First player, pick your hand"); - 11 @A let salt = randomUInt256(); - 12 @verifiably!(A) let commitment = digest([salt, handA]); - 13 publish! A -> commitment; deposit! A -> wagerAmount; - 14 - 15 @B assert! canReach(end, end.outcome == B_Wins); - 16 @B let handB = Hand.input("Second player, pick your hand"); - 17 publish! B -> handB; deposit! B -> wagerAmount; - 18 - 19 publish! A -> salt, handA; - 20 verify! commitment; - 21 let outcome = winner(handA, handB); - 22 end: switch(outcome) { - 23 | A_Wins => withdraw! A <- 2*wagerAmount - 24 | B_Wins => withdraw! B <- 2*wagerAmount - 25 | Draw => withdraw! A <- wagerAmount; withdraw! B <- wagerAmount }} - -2. A `Hand` can only be `Rock, Paper or Scissors` -3. There are only three possible `Outcome` either `B_wins`, `A_wins`, or its a `Draw` -4. Now define a function `winner`, that when given two hands can determine the `Outcome` -5. This is an arithmetic trick that translates each of the nine possible hand combinations to three possible outcomes -6. - -7. Alice and Bob use this contract -8. Declare the `rockPaperScissors` contract that has the `wagerAmount` -9. `@Alice` makes sure (`assert!`) that it's possible to reach the `end:` label -10. `@Alice` asks (`input`) and stores the value of her Hand. -11. `@Alice` creates a random value (`salt`) that will be used to obfuscate her Hand -12. `@Alice` store the obfuscated value of her Hand in a `verifiably` commitment -13. `@Alice` makes her commitment public and `deposit!` her wage. -14. - -15. `@Bob` makes sure he can reach the `end.outcome` where he wins -16. `@Bob` can `input` what hand he chooses to play -17. `@Bob` publishes his Hand and deposits his wager -18. - -19. Now it's possible to publish the `salt` and in the next step, use it to -20. `verify!` that the `commitment` was obfuscated with the salt -21. now we calculate the `outcome` as the result of evaluating the `winner` function with both hands. -22. `switch` for pattern matching, it's possible to select the appropriate outcome. -23. if `outcome` is `A_wins` `withdraw` to Alice both wages. -24. if `outcome` is `B_wins` `withdraw` to Bob both wages. -25. if `outcome` is `Draw` `withdraw` to give back their money to Alice and Bob. - - -## Lessons learned - -- You can define your data types with `data Hand` -- You can define smaller functions that are used later in the contract. Like: `let winner = (handA:Hand, handB:Hand)` -- You can use `switch` to do pattern matching From ebc608b2709e9b01381ea6e8e77788047a1ea31a Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:06:41 +0000 Subject: [PATCH 92/99] Delete 2021-02-03_07-00-00_deadman-switch-en.md --- .../2021-02-03_07-00-00_deadman-switch-en.md | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md b/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md deleted file mode 100644 index 4926fc298..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_deadman-switch-en.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Deadman switch -description: How to create a deadman switch? -order: 5 -last_updated: "2021-02-25T09:00:00+01:00" ---- -# How to create a deadman switch? - -Let's suppose a millionaire unlce has called you because he will give you the password to all his fortune. -However, while you are traveling to see your relative he passes away, and only he knew the password for the safe! - -Six months later, you get an email with the password for the safe and it turns out that your uncle had a *dead man switch* that would automatically reveal the password. - -In this contract, we are going to see how your uncle implemented that contract in Glow. - -## Visualization - -![img](https://ucarecdn.com/8b0ba880-443f-4b43-991d-ed5ac2dd2350/deadmanswitch.png) - - -## Glow Code - - 1 #lang glow - 2 // -*- JavaScript -*- - 3 // Inspired by https://github.com/KarolTrzeszczkowski/Electron-Cash-Last-Will-Plugin - 4 - 5 data Command = Withdraw(x : Nat) | Inherit(x : Nat) - 6 - 7 @interaction([Owner, Heir]) - 8 let deadManSwitch = (expirationDelay) => { - 9 let rec loop = (expirationTimestamp) => - 10 choice { - 11 | @_ deposit! x ; - 12 loop (expirationtimestamp); - 13 | @owner publish! withdraw(x); - 14 withdraw! owner <- x ; - 15 loop (now() + expirationdelay); - 16 | @heir publish! inherit(x); - 17 require! now() >= expirationtimestamp; - 18 withdraw! heir <- x; - 19 }; - 20 loop(now() + expirationdelay); - 21 } - -- 5 on this contract, there are only two actions, either withdraw or inherit. -- 7 and there are only two participants, the Owner of the fortune and you. -- 8 When creating the contract, the Owner must say how often he wants it to renew. For example, every six months. -- 20 The first time we go into the loop, it starts -- 9 Now the `loop` is a function that can call itself (recursive). -- 10 Is like pattern matching but based on whom performs the action -- 11 If there is a deposit, the contract continues. -- 13 In order to show that it's still alive, the Owner publishes on the blockchain that he wants to withdraw a little bit of the funds in the contract. -- 15 It renews the *dead man switch* with a new deadline. -- 16 When the `@heir` signals on the blockchain that is ready to inherit. - -The contract checks if the current block is past the expiration day. -If this is the case, the funds are released to the `heir`. - - -## Lessons learned - -- How to use explicit timestamps -- How to use recursive functions From cc41c8c09bad0e829a487a7a1090ced34c0de762 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:06:54 +0000 Subject: [PATCH 93/99] Delete 2021-02-03_07-00-00_crowdfund-en.md --- .../en/2021-02-03_07-00-00_crowdfund-en.md | 106 ------------------ 1 file changed, 106 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md b/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md deleted file mode 100644 index da0b2c0b3..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_crowdfund-en.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Crowdfund -description: How does Crowdfunding.glow work? -order: 7 -last_updated: "2021-02-25T09:00:00+01:00" ---- -# How does Crowdfunding.glow work? - -In this day and age, crowdfunding campaigns are well known. -Platforms like kickstarter.com and GoFund.me have made the crowdfunding model well known across the world -as an excellent way to bring together the resources of several parties that do not know each other -and yet are willing to contribute some money towards a common goal. - - -## Glow code - - 1 data Action = Pledge(TokenAmount) | Close | Reclaim(TokenAmount); - 2 - 3 let platformCommission amount = quotient(amount, 100); - 4 - 5 @interaction - 6 let crowdfunding = (target: TokenAmount, - 7 expirationTime : Timestamp) => { - 8 require! expirationTime > currentTime(); - 9 - 10 let rec crowdfund = (ledger : Table(TokenAmount <- Participant), - 11 totalPledged: TokenAmount) => { - 12 assert! totalPledged == totalAmount(ledger); - 13 choice { - 14 | ForAllParticipant (NewPledger) { - 15 @NewPledger amount = - 16 input(["Enter next pledge"], TokenAmount); - 17 publish! NewPledger -> Pledge(amount); - 18 deposit! NewPledger -> amount; - 19 require! currentTime() < expirationTime; - 20 crowdfund(Table.add(ledger, NewPledger, amount), - 21 totalPledged + amount); - 22 - 23 | publish! Organizer -> Success; - 24 require! currentTime() >= expirationTime; - 25 require! totalPledged >= target; - 26 let commission = platformCommission(totalPledged); - 27 withdraw! Platform <- commission; - 28 withdraw! Organizer <- totalPledged - commission; - 29 - 30 | ForAllParticipant(Pledger) - 31 publish! Pledger -> Reclaim(amount); - 32 require! currentTime() >= expirationTime; - 33 require! totalPledged < target; - 34 require! Table.get(ledger, Pledger) == amount; - 35 withdraw! Pledger <- amount; //(ref: return_amount_to_pledger) - 36 crowdfund(Table.remove(ledger, Pledger), //(ref: remove_pledger_from_ledger) - 37 totalPledged - amount); - 38 } - 39 crowdfund({}, 0); - 40 } - -- 7 When creating a campaign, there is a goal and an expiration time. - -- 11 We create a `ledger` where we record the `Pledgers` and the total amoun the campaign has raised so far - -Now three things can happen: - -- There is a new pledge -- The campaign was a successor -- A pledger reclaims a refund - -Let's look at all three in detail. - - -### Dealing with a new pledge - -Any participant can pledge 14. -The `NewPledger` must `deposit!` her amount to the contract 18. -And the pledge is stored in the `Ledger` 20. - - -### Campaign is successful - -23 When the organizer declares the campaign a success. -24 We must make sure the deadline for the campaign has passed and -25 The `totalPledged` surpassed the `target`. - - -### Pledger requests a reimbursement - -When a pledger requests a reimbursement 30. -We check that the expiration date has passed 32 and -that the goal wasn't achieved 33 . -Then we check that the amount that is reclaiming is the same we have stored in the Ledger 34. -We return the amount to the Pledger and remove it from the Ledger. - - -## Lessons learned - -- Explicit timeout -- Unrestricted open set of participants -- Choice restricted to timeouts and open participation - - -## Challenge - -Can you write a version of this contract that does the following: -a) Automatically decides if the campaign was successful or not (given the timeout). -b) Reimburses all the pledges automatically. From 0c0189a37bc426e2791605a0eefc6283b666f26b Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:07:08 +0000 Subject: [PATCH 94/99] Delete 2021-02-03_07-00-00_challenge-en.md --- .../en/2021-02-03_07-00-00_challenge-en.md | 180 ------------------ 1 file changed, 180 deletions(-) delete mode 100644 resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md diff --git a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md deleted file mode 100644 index d7ce53237..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Challenge -description: Translate a Solidity smart contract to Glow -order: 8 -last_updated: "2021-02-25T09:00:00+01:00" - ---- -# Challenge: Translate a Solidity smart contract to Glow - -In order to learn something new, we normally try to learn it refers to something we already know. -That's why in this article, we are going to learn the Glow smart contract language -by studying an example in Solidity and then translating it to Glow - - -## The Ballot example - -Ballot.sol is the first program that loads when looking going to the Remix IDE - - pragma solidity >=0.7.0 <0.8.0; - contract Ballot { - -Declare a struct called Voter that is a complex type -consisting of the weight of a vote, a Boolean voted, -the address of the Voter, and an index called vote. - - struct Voter { - uint weight;// Weight is accumulated by delegation - bool voted; // if true, that person already voted - address delegate;// person delegated to - uint vote; // index of the voted proposal - } - -You have an address type called chairperson. - - address chairperson; - -You have a mapping where you map and address with a voter - - mapping(address => Voter) voters; - -You also create an array of proposals where each proposal is a complex type struct. - - Proposal[] proposals; - - struct Proposal { - // If you can limit the length to a certain number of bytes, - // always use one of bytes1 to bytes32 because they are much cheaper - bytes32 name; // short name (up to 32 bytes) - uint voteCount;// number of accumulated votes - } - -In the constructor Ballot, you initialize the chairperson as the message sender with weight 1. -You also create a list of proposals. - - constructor(bytes32[] memory proposalNames) { - chairperson = msg.sender; - voters[chairperson].weight = 1; - - for (uint i = 0; i < proposalNames.length; i++) { - // 'Proposal({...})' creates a temporary - // Proposal object and 'proposals.push(...)' - // appends it to the end of 'proposals'. - proposals.push(Proposal({ - name: proposalNames[i], - voteCount: 0 - })); - } - } - -Give the `Voter` the right to vote on this ballot. -It can only be called by the `Chairperson`. -Validate that the voters have not voted yet and assign voters a weight. - - function giveRightToVote(address voter) public { - require( - msg.sender == chairperson, - "Only chairperson can give right to vote." - ); - require( - !voters[voter].voted, - "The voter already voted." - ); - require(voters[voter].weight == 0, - "the voter already had voting rights"); - voters[voter].weight = 1; - } - -Then the delegate() function delegates your vote to the Voter $(to) after a couple of validations -such as the message sender is not the to address has not voted. - - function delegate(address to) public { - Voter storage sender = voters[msg.sender]; - require(!sender.voted, "You already voted."); - require(to != msg.sender, "Self-delegation is disallowed."); - - while (voters[to].delegate != address(0)) { - to = voters[to].delegate; - - // We found a loop in the Delegation, not allowed. - require(to != msg.sender, "Found loop in delegation."); - } - sender.voted = true; - sender.delegate = to; - Voter storage delegate_ = voters[to]; - if (delegate_.voted) { - // If the delegate already voted, - // directly add to the number of votes - proposals[delegate_.vote].voteCount += sender.weight; - } else { - // If the delegate did not vote yet, - // add to her weight. - delegate_.weight += sender.weight; - } - } - -Give your vote (including votes delegated to you) to proposal - - function vote(uint proposal) public { - Voter storage sender = voters[msg.sender]; - require(sender.weight != 0, "Has no right to vote"); - require(!sender.voted, "Already voted."); - sender.voted = true; - sender.vote = proposal; - - // If 'proposal' is out of the range of the array, - // this will throw automatically and revert all - // changes. - proposals[proposal].voteCount += sender.weight; - } - -Find which is the proposal with the most votes. - - function winningProposal() public view - returns (uint winningProposal_) - { - uint winningVoteCount = 0; - for (uint p = 0; p < proposals.length; p++) { - if (proposals[p].voteCount > winningVoteCount) { - winningVoteCount = proposals[p].voteCount; - winningProposal_ = p; - } - } - } - -Get the name of the winning proposal - - function winnerName() public view - returns (bytes32 winnerName_) - { - winnerName_ = proposals[winningProposal()].name; - } - } - - -## Visualization - -By reading the previous contract, we can identify the following actors and flow: -The `Chairman` creates a contract with a defined number of options. -Then gives names to each option. -And grants voting rights to voters. -A voter (Bob in this diagram) can delegate his vote to another voter. -Voters vote for one of the options by its number. -Then everyone can ask who is winning by the one that has more votes. - -![img](https://ucarecdn.com/5dd5c388-7578-45a9-aea9-644d5ccf332c/ballot.png) - - -## How does the contract look in Glow? - -Now it is your turn. How does the previous smart contract look in Glow? - -Here are a few ideas on how you could get started with such a program: - -- One known proposal, one known voter -- Multiple known proposals, One known voter -- Multiple known proposals, Three known voters -- Multiple known proposals, Three known voters, with delegation -- Multiple known proposals, unknown voters, with delegation -- Multiple known proposals, unknown voters, with delegation, with giving voting rights From 1470cedacdb301fbfd4e08d50199f4f4c1debb62 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:09:55 +0000 Subject: [PATCH 95/99] Update 2021-02-25_07-00-00_glow-install-en.md code formatting tweaks --- .../articles/en/2021-02-25_07-00-00_glow-install-en.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md index d00ca2ba0..9300b7d64 100644 --- a/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md +++ b/resources/content/articles/en/2021-02-25_07-00-00_glow-install-en.md @@ -12,10 +12,11 @@ The first step is to install Glow so that you can get started. Glow can be insta To install Glow, follow these steps: 1. Open a terminal window (or any application on your system that allows you to enter shell commands). 2. Type the following command line: -`curl -L https://glow-lang.org/install/glow-install | sh` -This installation script first installs the [Nix](https://nixos.org/) package manager, which may require you to manually type yes, or y and/or type the administrator password to authorize parts of the installation. If you weren’t using Nix before, you may have to start a new shell for the PATH to be set up correctly and be able to run glow. + `curl -L https://glow-lang.org/install/glow-install | sh` -Note: If you use Linux or macOS on x86_64, all the binary packages for the software are cached, and the installation should only take a few minutes, depending on the speed of your internet connection. This software may require over 2GB of memory, so please ensure that you have enough available space on disk. If you use another platform, your computer may recompile code from source, so you should let it run overnight. +This installation script first installs the [Nix](https://nixos.org/) package manager, which may require you to manually type yes, or y and/or type the administrator password to authorize parts of the installation. If you were not using Nix before, you may have to start a new shell for the PATH to be set up correctly and be able to run glow. + +**Note**: If you use Linux or macOS on x86_64, all the binary packages for the software are cached, and the installation should only take a few minutes, depending on the speed of your internet connection. This software may require over 2GB of memory, so please ensure that you have enough available space on disk. If you use another platform, your computer may recompile code from source, so you should let it run overnight. We plan to release a Docker image soon, so please check back for updates. From 76068890ed098a54be70cc7ddf11ffe91ad58b40 Mon Sep 17 00:00:00 2001 From: IOHK Web Development user <55990349+iohkwebdev@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:15:16 +0000 Subject: [PATCH 96/99] Create 2021-02-25_07-00-00_glow-test-network-en.md --- ...021-02-25_07-00-00_glow-test-network-en.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md diff --git a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md new file mode 100644 index 000000000..16aedc800 --- /dev/null +++ b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md @@ -0,0 +1,167 @@ +--- +title: Setting up the Test Network +description: Setting up the Test Network +parent: 2021-02-03_07-00-00_getting-started +order: 2 +last_updated: "2021-02-25T09:00:00+01:00" +--- +## Setting up the Test Network + +By default, Glow will use the Cardano EVM Devnet (“ced”)—a public network on which you can interact with other users. You may experience a short delay of a minute or so when confirming each step of the interaction. + +For faster local-only tests with confirmations in a couple of seconds, you can instead run your own private Ethereum test network (“pet”) on your computer with these instructions. You should add the flags --evm-network pet to your invocations of Glow, as follows: + +`git clone https://github.com/fare/gerbil-ethereum.git +cd gerbil-ethereum +./scripts/run-ethereum-test-net.ss` + +### Creating Keys +Each participant must first generate their own identity on their own machine, with their own secret key, as follows: + +Alice: +`glow generate-identity --nickname Alice` + +Bob: +`glow generate-identity --nickname Bob` + +### Sharing Contact Information +After creating your key, you must share it with the other participant in the interaction (for example, using a chat application such as Slack). + +First, each participant lists their address using: +`glow list-identities` + +The listed addresses will appear in the following format (these are examples): +`Alice [ 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 ]` +`Bob [ 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD ]` + +Each participant then uses a copy and paste function to share their address with the other participant, who will register it as follows: +Alice replaces the address with Bob’s actual address, as follows: +`address=0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD` +`glow add-contact --nickname Bob --address ${address}` + +Bob replaces the address with Alice’s actual address, as follows: +`address=0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1` +`glow add-contact --nickname Alice --address ${address}` + +### Getting Tokens from the Faucet: +As your address is a new address it does not have any tokens to spend, or to use to pay for gas. To get some tokens for your address you can use the test network’s faucet, as follows: + +Alice runs: +`glow faucet --to Alice --evm-network pet` + +Bob runs: +`glow faucet --to Bob --evm-network pet` + +(If you are using your own private Ethereum test network, the two commands above and every command below (with the exception of the digest command) are where you must add the flags --evm-network pet to your invocations of glow.) + +### Configuring the Interactions +This section outlines how you should configure the contract interactions of Alice and Bob. + +#### Setting up Alice’s Interaction +One of the two participants writes a document for the other to sign. For example, Alice prepares the following document and sends it to Bob for review: + +`echo “Bob sells BLAH to Alice” > document.txt` + +When both agree on the document, they should each compute its digest with: + +`glow digest document.txt` + +Now, Alice can sign the interaction. In the scenario where you are running the interactions on the same machine, you should specify a database so the two users will not conflict with each other’s data; the extra database specification is not necessary if the users are running on different machines. + +`glow start-interaction --database run/Alice --evm-network pet` + +The CLI will then prompt Alice to select an application, choose which identity to use for the interaction, which role they will play in it, assign addresses to roles of the other identities, enter the interaction parameters, and finally, print the interaction agreement for Alice to send to Bob, so that he can configure his side of the interaction with the same parameters. + +Here is an example of what the setup should look like from Alice’s side: + +Choose application: +1) coin_flip +2) buy_sig +3) rps_simple +Enter number +> 2 + +Choose your identity: +1) Alice - 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 +Enter number +> 1 + +Choose your role: +1) Buyer +2) Seller +Enter number +> 1 + +Assign roles +Select address for Seller: +1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD +Enter number +> 1 + +Define parameters +Enter digest +> 0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20 +Enter price +> 1000 + +Max initial block [ Current block number is 350 ] +> 500 + +One line command for other participants to generate the same agreement: +./glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' +Setup interaction (Bob) + +Bob has a lot less steps since the agreement contains all of the parameters. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s when running both participants on the same machine. + +glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B + +Choose your identity: +1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD +Enter number +> 1 + +Choose your role: +1) Buyer +2) Seller +Enter number +> 2 + +Start interaction (Alice) + +After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything specified in the agreement. + +Send the handshake below to the other participant: +{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} + +Run interaction (Alice + Bob) + +All Bob has left to do is paste the handshake when prompted and the runtime will handle everything from there. First by generating a signature of the digest and then publishing it on-chain. Alice’s runtime will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. + +The last thing the runtime does is print all the variables that were bound during execution of the contract, with the signature being purchased highlighted for both participants. + +#### Setting up Bob's Interaction +Bob’s interaction does not require as many steps since the agreement contains all of the parameters already. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s, when running both participants on the same machine. + +glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B + +Choose your identity: +1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD +Enter number +> 1 + +Choose your role: +1) Buyer +2) Seller +Enter number +> 2 + +#### Starting Alice’s Interaction +After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything that is specified in the agreement. + +Send the handshake below to the other participant: +{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} + +#### Running the Alice and Bob Interaction +All Bob has left to do is paste the handshake when he is prompted to do so and the runtime component will handle everything from there. The first thing that will happen is that a signature of the digest is generated and then published on-chain. Alice’s runtime component will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. + +The last thing the runtime component does is to print all the variables that were bound during execution of the contract, with the signature that is being purchased highlighted for both participants. From 7f3378495eac72f3bc865f721e1c04112c5171a0 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:38:11 +0000 Subject: [PATCH 97/99] Update 2021-02-25_07-00-00_glow-test-network-en.md code formatting tweaks --- ...021-02-25_07-00-00_glow-test-network-en.md | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md index 16aedc800..d5b9c7e49 100644 --- a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md +++ b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md @@ -19,37 +19,46 @@ cd gerbil-ethereum Each participant must first generate their own identity on their own machine, with their own secret key, as follows: Alice: + `glow generate-identity --nickname Alice` Bob: + `glow generate-identity --nickname Bob` ### Sharing Contact Information After creating your key, you must share it with the other participant in the interaction (for example, using a chat application such as Slack). First, each participant lists their address using: + `glow list-identities` The listed addresses will appear in the following format (these are examples): + `Alice [ 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 ]` `Bob [ 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD ]` Each participant then uses a copy and paste function to share their address with the other participant, who will register it as follows: Alice replaces the address with Bob’s actual address, as follows: + `address=0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD` `glow add-contact --nickname Bob --address ${address}` Bob replaces the address with Alice’s actual address, as follows: + `address=0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1` + `glow add-contact --nickname Alice --address ${address}` ### Getting Tokens from the Faucet: As your address is a new address it does not have any tokens to spend, or to use to pay for gas. To get some tokens for your address you can use the test network’s faucet, as follows: Alice runs: + `glow faucet --to Alice --evm-network pet` Bob runs: + `glow faucet --to Bob --evm-network pet` (If you are using your own private Ethereum test network, the two commands above and every command below (with the exception of the digest command) are where you must add the flags --evm-network pet to your invocations of glow.) @@ -74,94 +83,87 @@ The CLI will then prompt Alice to select an application, choose which identity t Here is an example of what the setup should look like from Alice’s side: +``` Choose application: 1) coin_flip 2) buy_sig 3) rps_simple Enter number > 2 +``` +``` Choose your identity: 1) Alice - 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 Enter number > 1 +``` +``` Choose your role: 1) Buyer 2) Seller Enter number > 1 +``` +``` Assign roles Select address for Seller: 1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD Enter number > 1 +``` +``` Define parameters Enter digest > 0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20 Enter price > 1000 +``` +``` Max initial block [ Current block number is 350 ] > 500 +``` One line command for other participants to generate the same agreement: +``` ./glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' -Setup interaction (Bob) +``` -Bob has a lot less steps since the agreement contains all of the parameters. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s when running both participants on the same machine. - -glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B - -Choose your identity: -1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD -Enter number -> 1 - -Choose your role: -1) Buyer -2) Seller -Enter number -> 2 - -Start interaction (Alice) - -After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything specified in the agreement. - -Send the handshake below to the other participant: -{"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} - -Run interaction (Alice + Bob) - -All Bob has left to do is paste the handshake when prompted and the runtime will handle everything from there. First by generating a signature of the digest and then publishing it on-chain. Alice’s runtime will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. - -The last thing the runtime does is print all the variables that were bound during execution of the contract, with the signature being purchased highlighted for both participants. - -#### Setting up Bob's Interaction +#### Setting up Bob’s Interaction Bob’s interaction does not require as many steps since the agreement contains all of the parameters already. He just needs to specify which identity and role he is going to use in the interaction. Note also the database option that was appended to separate Bob’s database from Alice’s, when running both participants on the same machine. +``` glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B +``` +``` Choose your identity: 1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD Enter number > 1 +``` +``` Choose your role: 1) Buyer 2) Seller Enter number > 2 +``` #### Starting Alice’s Interaction -After setting up the interaction, the Glow runtime will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything that is specified in the agreement. +After setting up the interaction, the Glow runtime component will deploy an EVM smart contract to the configured network and generate a handshake to send to Bob. The handshake is for Bob to verify that the on-chain contract corresponds to everything that is specified in the agreement. Send the handshake below to the other participant: +``` {"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} +``` -#### Running the Alice and Bob Interaction -All Bob has left to do is paste the handshake when he is prompted to do so and the runtime component will handle everything from there. The first thing that will happen is that a signature of the digest is generated and then published on-chain. Alice’s runtime component will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. +##### Running the Alice and Bob Interaction +All Bob has left to do is paste the handshake when prompted and the runtime will handle everything from there. First by generating a signature of the digest and then publishing it on-chain. Alice’s runtime will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. -The last thing the runtime component does is to print all the variables that were bound during execution of the contract, with the signature that is being purchased highlighted for both participants. +The last thing the runtime does is print all the variables that were bound during execution of the contract, with the signature being purchased highlighted for both participants. From 89570c1fed0b6297d7226aff75890aa609c3528b Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:53:16 +0000 Subject: [PATCH 98/99] Update 2021-02-25_07-00-00_glow-test-network-en.md fix heading --- .../en/2021-02-25_07-00-00_glow-test-network-en.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md index d5b9c7e49..4893057cc 100644 --- a/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md +++ b/resources/content/articles/en/2021-02-25_07-00-00_glow-test-network-en.md @@ -82,7 +82,6 @@ Now, Alice can sign the interaction. In the scenario where you are running the i The CLI will then prompt Alice to select an application, choose which identity to use for the interaction, which role they will play in it, assign addresses to roles of the other identities, enter the interaction parameters, and finally, print the interaction agreement for Alice to send to Bob, so that he can configure his side of the interaction with the same parameters. Here is an example of what the setup should look like from Alice’s side: - ``` Choose application: 1) coin_flip @@ -91,14 +90,12 @@ Choose application: Enter number > 2 ``` - ``` Choose your identity: 1) Alice - 0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1 Enter number > 1 ``` - ``` Choose your role: 1) Buyer @@ -106,7 +103,6 @@ Choose your role: Enter number > 1 ``` - ``` Assign roles Select address for Seller: @@ -114,7 +110,6 @@ Select address for Seller: Enter number > 1 ``` - ``` Define parameters Enter digest @@ -122,12 +117,10 @@ Enter digest Enter price > 1000 ``` - ``` Max initial block [ Current block number is 350 ] > 500 ``` - One line command for other participants to generate the same agreement: ``` ./glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' @@ -139,14 +132,12 @@ Bob’s interaction does not require as many steps since the agreement contains ``` glow start-interaction --agreement '{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"}' --evm-network pet --database run/B ``` - ``` Choose your identity: 1) Bob - 0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD Enter number > 1 ``` - ``` Choose your role: 1) Buyer @@ -163,7 +154,7 @@ Send the handshake below to the other participant: {"agreement":{"glow-version":"Glow v0.0-894-g575c859","interaction":"mukn/glow/examples/buy_sig#payForSignature","participants":{"Buyer":"0xa71CEb0990dD1f29C2a064c29392Fe66baf05aE1","Seller":"0xb0bb1ed229f5Ed588495AC9739eD1555f5c3aabD"},"parameters":{"digest":"0x07887c5873ad098e96297f041eb0736ed50d33cf7010f1786f63cddf3b0b8b20","price":"0x3e8"},"reference":{},"options":{"blockchain":"Private Ethereum Testnet","timeoutInBlocks":"0x1f4","maxInitialBlock":"0x1f4"},"code-digest":"0x16c5659f6e3c70f0c53ac5abf3977e658093f1f5880bd478de8d3a87c92d9607"},"contract-config":{"contract-address":"0x9533A6610DBd92fa5C9E46364b2b36b8D37C1874","code-hash":"0x30e92fcb774f9f205242dce3f112025f999f18c6d45971f4fc48ed8fa807c1d9","creation-hash":"0xb9a04dea24f5fee9b7cbb3f4446d124bc884e869195e9d91e975ad2e3bc2a30b","creation-block":"0x16de"},"published-data":"0x"} ``` -##### Running the Alice and Bob Interaction +#### Running the Alicea and Bob Interaction All Bob has left to do is paste the handshake when prompted and the runtime will handle everything from there. First by generating a signature of the digest and then publishing it on-chain. Alice’s runtime will then watch the network for transactions against the contract to see Bob’s move, and both runtimes should run to completion without requiring any more user input. The last thing the runtime does is print all the variables that were bound during execution of the contract, with the signature being purchased highlighted for both participants. From 6c0becacd83ca7a5607200e3b8400d494e6ba555 Mon Sep 17 00:00:00 2001 From: Niamh Ahern <34340946+nahern@users.noreply.github.com> Date: Thu, 25 Feb 2021 16:18:03 +0000 Subject: [PATCH 99/99] Update 2021-02-03_07-00-00_glow-tutorial-en.md updating tutorial copy --- .../articles/en/2021-02-03_07-00-00_glow-tutorial-en.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md index 8cde09373..2489fd9d9 100644 --- a/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md +++ b/resources/content/articles/en/2021-02-03_07-00-00_glow-tutorial-en.md @@ -8,7 +8,4 @@ last_updated: "2021-02-25T09:00:00+01:00" # Glow Tutorial -Glow is a language for developing secure decentralized apps (DApps) that can run on different blockchains. - -In this tutorial, we analyze the sample programs that are provided in the Glow distribution to learn -how they work, and how could they can be applied to smart contract and DApp development. +We’ll update this section soon with tutorials and guides. Make sure you sign up to our [devnets newsletter](https://mailchi.mp/iohk/devdigest) to get the latest updates delivered to your inbox

|YlMI1yrrztBgdK&AYl&+ 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 literal 0 HcmV?d00001 diff --git a/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png b/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/deadmanswitch.png new file mode 100644 index 0000000000000000000000000000000000000000..bc304e18fb08e7ccbc1341cd9cbbefdefe48a35f GIT binary patch literal 75906 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 literal 0 HcmV?d00001 diff --git a/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png b/resources/content/articles/article-images/2021-02-03_07-00-00_learning-glow-by-example/rps-min.png new file mode 100644 index 0000000000000000000000000000000000000000..f4920c2ce830b3d72c9e110d072498031cdce6aa GIT binary patch literal 56679 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