From fbb4c5eecdb81347873d2019ab99fb7ebf066e45 Mon Sep 17 00:00:00 2001 From: "dmitry.shakhtarin" Date: Sun, 9 Sep 2018 10:44:47 +0300 Subject: [PATCH] summirizing contract --- .../scala/fluence/hackethberlin/Expr.scala | 21 +++-- src/main/scala/fluence/Auction.scala | 88 +++++++++++++++++++ src/main/scala/fluence/MakeVyperApp.scala | 87 +----------------- 3 files changed, 105 insertions(+), 91 deletions(-) create mode 100644 src/main/scala/fluence/Auction.scala diff --git a/core/src/main/scala/fluence/hackethberlin/Expr.scala b/core/src/main/scala/fluence/hackethberlin/Expr.scala index 74f8f16..59609e9 100644 --- a/core/src/main/scala/fluence/hackethberlin/Expr.scala +++ b/core/src/main/scala/fluence/hackethberlin/Expr.scala @@ -1,7 +1,9 @@ package fluence.hackethberlin import cats.free.Free +import shapeless._ import types._ +import syntax.singleton._ sealed trait Expr[T] { def boxedValue: T @@ -88,14 +90,14 @@ object Expr { def `+:+`[A <: timestamp.type, B <: timedelta.type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[timestamp.type] = Infix("+", a, b, timestamp) - def `if`(expr: InlineExpr[bool.type], body: () ⇒ Free[Expr, Void]): InlineExpr[Void] = - RightBody("if", expr, Void, body) + def `if`(expr: InlineExpr[bool.type], body: () ⇒ Free[Expr, Void]): Free[Expr, Void.type] = + RightBody("if", expr, Void, body).liftF def `not`[A <: bool.type](expr: InlineExpr[A]): InlineExpr[bool.type] = Right("not", expr, bool) - def `assertt`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = - Right("assert", expr, bool) + def `assert`(expr: InlineExpr[bool.type]): Free[Expr, bool.type] = + Right("assert", expr, bool).liftF def `<<`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = Infix("<", a, b, bool) @@ -107,5 +109,14 @@ object Expr { Infix(">", a, b, bool) } - object Defs extends Defs + object Defs extends Defs { + val predef = ProductType( + (Symbol("block.timestamp") ->> timestamp) :: + (Symbol("msg.value") ->> wei_value) :: + (Symbol("msg.sender") ->> address) :: + (Symbol("True") ->> bool) :: + (Symbol("False") ->> bool) :: + HNil + ) + } } diff --git a/src/main/scala/fluence/Auction.scala b/src/main/scala/fluence/Auction.scala new file mode 100644 index 0000000..8ae9649 --- /dev/null +++ b/src/main/scala/fluence/Auction.scala @@ -0,0 +1,88 @@ +package fluence + +import hackethberlin._ +import hackethberlin.types._ +import shapeless._ +import Decorator._ +import syntax.singleton._ +import cats.free.Free +import fluence.hackethberlin.{Contract, Expr, FuncDef} +import fluence.hackethberlin.types.{ProductType, Void, `public`} +import shapeless.HNil + +object Auction extends App { + import Expr.Defs._ + + val `block.timestamp` = predef.ref(Symbol("block.timestamp")) + val `msg.value` = predef.ref(Symbol("msg.value")) + val `msg.sender` = predef.ref(Symbol("msg.sender")) + val `True` = predef.ref('True) + + val data = ProductType.self( + ('beneficiary ->> public(address)) :: + ('auction_start ->> public(timestamp)) :: + ('auction_end ->> public(timestamp)) :: + ('highest_bidder ->> `public`(address)) :: + ('highest_bid ->> `public`(wei_value)) :: + ('ended ->> public(bool)) :: HNil + ) + + val beneficiary = data.ref('beneficiary) + val auction_start = data.ref('auction_start) + val auction_end = data.ref('auction_end) + val highest_bid = data.ref('highest_bid) + val highest_bidder = data.ref('highest_bidder) + val ended = data.ref('ended) + + val initArgs = ProductType(('_beneficiary ->> address) :: ('_bidding_time ->> timedelta) :: HNil) + + val _beneficiary = initArgs.ref('_beneficiary) + val _bidding_time = initArgs.ref('_bidding_time) + + val init = `@public` @: initArgs.funcDef( + "__init__", + Void + ) { args ⇒ + for { + _ <- Free.pure(Void) + _ <- beneficiary :=: _beneficiary + _ <- auction_start :=: `block.timestamp` + _ <- auction_end :=: `+:+`(auction_start, _bidding_time) + } yield Void + } + + val bidIf: () ⇒ Free[Expr, Void] = { () => + for { + _ <- FuncDef.send(highest_bidder :: highest_bid :: HNil).liftF + } yield Void + } + + val bid = `@public` @: `@payable` @: ProductType.hNil.funcDef( + "bid", + Void + ) { args ⇒ + for { + _ <- `assert`(`<<`(`block.timestamp`, auction_end)) + _ <- `assert`(`>>`(`msg.value`, highest_bid)) + _ <- `if`(`not`(`:===:`(highest_bid, `msg.value`)), bidIf) + _ <- highest_bidder :=: `msg.sender` + _ <- highest_bid :=: `msg.value` + } yield Void + } + + val end_auction = `@public` @: ProductType.hNil.funcDef( + "end_auction", + Void + ) { args ⇒ + for { + _ <- `assert`(`>=`(`block.timestamp`, auction_end)) + _ <- `assert`(`not`(ended)) + _ <- ended :=: `True` + _ <- FuncDef.send(beneficiary :: highest_bid :: HNil).liftF + } yield Void + } + + val contract = new Contract(data :: init :: bid :: end_auction :: HNil) + + println(contract.toVyper) +} diff --git a/src/main/scala/fluence/MakeVyperApp.scala b/src/main/scala/fluence/MakeVyperApp.scala index 8f38a11..a4723f1 100644 --- a/src/main/scala/fluence/MakeVyperApp.scala +++ b/src/main/scala/fluence/MakeVyperApp.scala @@ -51,7 +51,7 @@ object MakeVyperApp extends App { sumArgs.funcDef("sum", uint256) { args ⇒ for { c ← 'c :=: `++`(args.ref('a), args.ref('b)) - _ ← Free.pure(`++`(args.ref('a), args.ref('b))) + _ ← `++`(args.ref('a), args.ref('b)) d ← 'd :=: `++`(args.ref('b), c) _ ← d :=: c sum ← `++`(args.ref('a), d).toReturn @@ -70,88 +70,3 @@ object MakeVyperApp extends App { // println(s"MMMMMACRO\n\n ${new MyContract("abc", 123).toAST.toVyper}") } - -object Auction extends App { - import Expr.Defs._ - - val predef = ProductType( - (Symbol("block.timestamp") ->> timestamp) :: - (Symbol("msg.value") ->> wei_value) :: - (Symbol("msg.sender") ->> address) :: - (Symbol("True") ->> bool) :: - HNil - ) - - val `block.timestamp` = predef.ref(Symbol("block.timestamp")) - val `msg.value` = predef.ref(Symbol("msg.value")) - val `msg.sender` = predef.ref(Symbol("msg.sender")) - val `True` = predef.ref('True) - - val data = ProductType.self( - ('beneficiary ->> public(address)) :: - ('auction_start ->> public(timestamp)) :: - ('auction_end ->> public(timestamp)) :: - ('highest_bidder ->> `public`(address)) :: - ('highest_bid ->> `public`(wei_value)) :: - ('ended ->> public(bool)) :: HNil - ) - - val beneficiary = data.ref('beneficiary) - val auction_start = data.ref('auction_start) - val auction_end = data.ref('auction_end) - val highest_bid = data.ref('highest_bid) - val highest_bidder = data.ref('highest_bidder) - val ended = data.ref('ended) - - val initArgs = ProductType(('_beneficiary ->> address) :: ('_bidding_time ->> timedelta) :: HNil) - - val _beneficiary = initArgs.ref('_beneficiary) - val _bidding_time = initArgs.ref('_bidding_time) - - val init = `@public` @: initArgs.funcDef( - "__init__", - Void - ) { args ⇒ - for { - _ <- Free.pure(Void) - _ <- beneficiary :=: _beneficiary - _ <- auction_start :=: `block.timestamp` - _ <- auction_end :=: `+:+`(auction_start, _bidding_time) - } yield Void - } - - val bidIf: () ⇒ Free[Expr, Void] = { () => - for { - _ <- FuncDef.send(highest_bidder :: highest_bid :: HNil).liftF - } yield Void - } - - val bid = `@public` @: `@payable` @: ProductType.hNil.funcDef( - "bid", - Void - ) { args ⇒ - for { - _ <- `assertt`(`<<`(`block.timestamp`, auction_end)).liftF - _ <- `assertt`(`>>`(`msg.value`, highest_bid)).liftF - _ <- `if`(`not`(`:===:`(highest_bid, `msg.value`)), bidIf).liftF - _ <- highest_bidder :=: `msg.sender` - _ <- highest_bid :=: `msg.value` - } yield Void - } - - val end_auction = `@public` @: ProductType.hNil.funcDef( - "end_auction", - Void - ) { args ⇒ - for { - _ <- `assertt`(`>=`(`block.timestamp`, auction_end)).liftF - _ <- `assertt`(`not`(ended)).liftF - _ <- ended :=: `True` - _ <- FuncDef.send(beneficiary :: highest_bid :: HNil).liftF - } yield Void - } - - val contract = new Contract(data :: init :: bid :: end_auction :: HNil) - - println(contract.toVyper) -}