Merge branch 'master' of https://github.com/fluencelabs/hackethberlin into publisher

This commit is contained in:
Dmitry Sergeev 2018-09-09 10:13:32 +02:00
commit 71b5d0a805
5 changed files with 126 additions and 111 deletions

View File

@ -32,10 +32,11 @@ This _crazy_ Scala code:
```scala ```scala
val f = `@public` @: val f = `@public` @:
sumArgs.funcDef("sum", uint256) { args ⇒ sumArgs.funcDef("sumSome", uint256) { args ⇒
for { for {
c ← 'c :=: `++`(args.ref('a), args.ref('b)) c ← 'c :=: `++`(args.ref('a), args.ref('b))
d ← 'd :=: `++`(args.ref('b), c) d ← 'd :=: `++`(args.ref('b), c)
_ ← d :=: c
sum ← `++`(args.ref('a), d).toReturn sum ← `++`(args.ref('a), d).toReturn
} yield sum } yield sum
} }
@ -49,14 +50,15 @@ Compiles into this:
```python ```python
@public @public
def sum(a: uint256, b: uint256) -> uint256: def sumSome(a: uint256, b: uint256) -> uint256:
c = a + b c = a + b
d = b + c d = b + c
d = c
return a + d return a + d
``` ```
This smart contract is deployed on [Rinkeby](some link to rinkeby scanner). Hooray! The more sophisticated [Auction example](https://github.com/fluencelabs/hackethberlin/blob/master/src/main/scala/fluence/Auction.scala) is deployed on [Rinkeby](https://rinkeby.etherscan.io/address/0xdfe0c07c8c6bb3fd9a7fd6ee45bd2c086374f13c). Hooray!
## Future plans ## Future plans

View File

@ -1,7 +1,9 @@
package fluence.hackethberlin package fluence.hackethberlin
import cats.free.Free import cats.free.Free
import shapeless._
import types._ import types._
import syntax.singleton._
sealed trait Expr[T] { sealed trait Expr[T] {
def boxedValue: T def boxedValue: T
@ -56,6 +58,7 @@ object Expr {
boxedValue: T, boxedValue: T,
body: () Free[Expr, Void] body: () Free[Expr, Void]
) extends InlineExpr[T] { ) extends InlineExpr[T] {
def bodyVyper: String = def bodyVyper: String =
body().foldMap(CodeChunk.fromExpr).run._1.toVyper(2) body().foldMap(CodeChunk.fromExpr).run._1.toVyper(2)
override def toVyper: String = s"$op " + right.toVyper + s":\n$bodyVyper" override def toVyper: String = s"$op " + right.toVyper + s":\n$bodyVyper"
@ -85,17 +88,20 @@ object Expr {
def `:===:`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = def `:===:`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] =
Infix("==", a, b, bool) Infix("==", a, b, bool)
def `+:+`[A <: timestamp.type, B <: timedelta.type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[timestamp.type] = def `+:+`[A <: timestamp.type, B <: timedelta.type](
a: InlineExpr[A],
b: InlineExpr[B]
): InlineExpr[timestamp.type] =
Infix("+", a, b, timestamp) Infix("+", a, b, timestamp)
def `if`(expr: InlineExpr[bool.type], body: () Free[Expr, Void]): InlineExpr[Void] = def `if`(expr: InlineExpr[bool.type], body: () Free[Expr, Void]): Free[Expr, Void.type] =
RightBody("if", expr, Void, body) RightBody("if", expr, Void, body).liftF
def `not`[A <: bool.type](expr: InlineExpr[A]): InlineExpr[bool.type] = def `not`[A <: bool.type](expr: InlineExpr[A]): InlineExpr[bool.type] =
Right("not", expr, bool) Right("not", expr, bool)
def `assertt`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = def `assert`(expr: InlineExpr[bool.type]): Free[Expr, bool.type] =
Right("assert", expr, bool) Right("assert", expr, bool).liftF
def `<<`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = def `<<`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] =
Infix("<", a, b, bool) Infix("<", a, b, bool)
@ -107,5 +113,33 @@ object Expr {
Infix(">", a, b, bool) Infix(">", a, b, bool)
} }
object Defs extends Defs object Defs extends Defs {
import types._
import syntax.singleton._
val send =
ProductType(('_addr ->> `public`(address)) :: ('_money ->> `public`(wei_value)) :: HNil).funcDef(
"send",
Void
) { args
for {
_ <- Free.pure(Void)
} yield Void
}
val predef = ProductType(
(Symbol("block.timestamp") ->> timestamp) ::
(Symbol("msg.value") ->> wei_value) ::
(Symbol("msg.sender") ->> address) ::
(Symbol("True") ->> bool) ::
(Symbol("False") ->> 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)
}
} }

View File

@ -47,18 +47,4 @@ object FuncDef {
mapped: ops.hlist.Mapped[_Values, InlineExpr] mapped: ops.hlist.Mapped[_Values, InlineExpr]
)(implicit values: ops.record.Values.Aux[Args, _Values]): FuncDef[Args, types.Void, mapped.Out] = )(implicit values: ops.record.Values.Aux[Args, _Values]): FuncDef[Args, types.Void, mapped.Out] =
new FuncDef(name, ProductType(argsDef), types.Void, args body(args).map(_ types.Void)) new FuncDef(name, ProductType(argsDef), types.Void, args body(args).map(_ types.Void))
import types._
import syntax.singleton._
val send = {
ProductType(('_addr ->> `public`(address)) :: ('_money ->> `public`(wei_value)) :: HNil).funcDef(
"send",
Void
) { args
for {
_ <- Free.pure(Void)
} yield Void
}
}
} }

View File

@ -0,0 +1,78 @@
package fluence
import hackethberlin._
import hackethberlin.types._
import shapeless._
import Decorator._
import syntax.singleton._
import fluence.hackethberlin.{Contract, Expr}
import fluence.hackethberlin.types.{`public`, ProductType, Void}
import shapeless.HNil
object Auction extends App {
import Expr.Defs._
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 {
_ <- beneficiary :=: _beneficiary
_ <- auction_start :=: `block.timestamp`
_ <- auction_end :=: `+:+`(auction_start, _bidding_time)
} 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`)), {
() =>
send(highest_bidder :: highest_bid :: HNil).liftF.map(_ => Void)
})
_ <- 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`
_ <- send(beneficiary :: highest_bid :: HNil).liftF.map(_ => Void)
} yield Void
}
val contract = new Contract(data :: init :: bid :: end_auction :: HNil)
println(contract.toVyper)
}

View File

@ -48,16 +48,17 @@ object MakeVyperApp extends App {
import Expr.Defs._ import Expr.Defs._
val f = `@public` @: val f = `@public` @:
sumArgs.funcDef("sum", uint256) { args sumArgs.funcDef("sumSome", uint256) { args
for { for {
c 'c :=: `++`(args.ref('a), args.ref('b)) c 'c :=: `++`(args.ref('a), args.ref('b))
_ Free.pure(`++`(args.ref('a), args.ref('b)))
d 'd :=: `++`(args.ref('b), c) d 'd :=: `++`(args.ref('b), c)
_ d :=: c _ d :=: c
sum `++`(args.ref('a), d).toReturn sum `++`(args.ref('a), d).toReturn
} yield sum } yield sum
} }
println(f.toVyper)
val all = recordStruct :: data :: func :: f :: HNil val all = recordStruct :: data :: func :: f :: HNil
val c = new Contract(recordStruct :: struct :: data :: func :: f :: HNil) val c = new Contract(recordStruct :: struct :: data :: func :: f :: HNil)
@ -67,91 +68,5 @@ object MakeVyperApp extends App {
println( println(
func(recordStruct.ref('record_address) :: HNil).toVyper func(recordStruct.ref('record_address) :: HNil).toVyper
) )
// println(s"MMMMMACRO\n\n ${new MyContract("abc", 123).toAST.toVyper}") // 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)
}