mirror of
https://github.com/fluencelabs/hackethberlin
synced 2025-04-24 17:02:18 +00:00
Merge branch 'master' of https://github.com/fluencelabs/hackethberlin into publisher
This commit is contained in:
commit
71b5d0a805
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
78
src/main/scala/fluence/Auction.scala
Normal file
78
src/main/scala/fluence/Auction.scala
Normal 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)
|
||||||
|
}
|
@ -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)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user