Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial attempt at a raffle contract #1

Merged
merged 3 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Integration Tests

on:
pull_request:
branches: [main]
push:
branches: [main]


jobs:
tests:
name: Flow CLI Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: "true"
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: Install Flow CLI
run: bash -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" -- v1.8.0
- name: Run tests
run: sh ./run-tests.sh
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coverage.json
coverage.lcov
.idea
*.pkey
*.private
*.pem

node_modules
153 changes: 153 additions & 0 deletions contracts/Raffles.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import "MetadataViews"

pub contract Raffles {
pub let ManagerStoragePath: StoragePath
pub let ManagerPublicPath: PublicPath

pub event RaffleCreated(address: Address, raffleID: UInt64, sourceType: Type)
pub event RaffleDrawn(address: Address, raffleID: UInt64, sourceType: Type, index: Int, value: String)

pub struct Details {
pub let start: UInt64?
pub let end: UInt64?
pub let display: MetadataViews.Display

init(
_ start: UInt64?,
_ end: UInt64,
_ display: MetadataViews.Display

) {
self.start = start
self.end = end
self.display = display
}
}

pub resource interface RafflePublic {
pub fun getEntryAt(index: Int): AnyStruct
}

pub resource Raffle: RafflePublic, MetadataViews.Resolver {
pub let source: @{RaffleSource}
pub let details: Details

pub fun draw(): Int {
return self.source.draw()
}

pub fun getEntryAt(index: Int): AnyStruct {
return self.source.getEntryAt(index: index)
}

pub fun getViews(): [Type] {
return [
Type<MetadataViews.Display>()
]
}

pub fun resolveView(_ type: Type): AnyStruct? {
switch type {
case Type<MetadataViews.Display>():
return self.details.display
}

return nil
}

init(
source: @{RaffleSource},
details: Details
) {
self.source <- source
self.details = details
}

destroy() {
destroy self.source
}
}

pub resource interface RaffleSource {
pub fun draw(): Int
pub fun getEntryAt(index: Int): AnyStruct
}

pub resource AddressRaffleSource: RaffleSource {
pub let addresses: [Address]

pub fun draw(): Int {
let r = revertibleRandom()
return Int(UInt64(self.addresses.length) % r)
austinkline marked this conversation as resolved.
Show resolved Hide resolved
}

pub fun getEntryAt(index: Int): AnyStruct {
austinkline marked this conversation as resolved.
Show resolved Hide resolved
return self.addresses[index]
}

init() {
self.addresses = []
}
}

pub resource interface ManagerPublic {
pub fun borrowRafflePublic(id: UInt64): &{RafflePublic}?
}

pub resource Manager: ManagerPublic {
access(self) let raffles: @{UInt64: Raffle}

pub fun borrowRafflePublic(id: UInt64): &{RafflePublic}? {
if self.raffles[id] == nil {
return nil
}

return &self.raffles[id] as &Raffle?
}

init() {
self.raffles <- {}
}

destroy () {
destroy self.raffles
}
}

access(contract) fun emitDrawing(address: Address, raffleID: UInt64, sourceType: Type, index: Int, value: AnyStruct) {
var v = "UNKNOWN"
switch value.getType() {
case Type<Address>():
v = (value as! Address).toString()
break
case Type<UInt64>():
v = (value as! UInt64).toString()
break
}

emit RaffleDrawn(address: address, raffleID: raffleID, sourceType: sourceType, index: index, value: v)
}

pub fun createManager(): @Manager {
return <- create Manager()
}

pub fun createRaffle(source: @{RaffleSource}, details: Details): @Raffle {
return <- create Raffle(source: <- source, details: details)
}

pub fun createRaffleSource(_ type: Type): @{RaffleSource} {
switch type {
case Type<@AddressRaffleSource>():
return <- create AddressRaffleSource()
}

panic("raffle source type ".concat(type.identifier).concat(" is not valid"))
}

init() {
let identifier = "Raffle_".concat(self.account.address.toString())
self.ManagerStoragePath = StoragePath(identifier: identifier)!
self.ManagerPublicPath = PublicPath(identifier: identifier)!
}
}
113 changes: 113 additions & 0 deletions flow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"networks": {
"emulator": "127.0.0.1:3569",
"mainnet": "access.mainnet.nodes.onflow.org:9000",
"testing": "127.0.0.1:3569",
"testnet": "access.devnet.nodes.onflow.org:9000"
},
"accounts": {
"emulator-account": {
"address": "0xf8d6e0586b0a20c7",
"key": "f2e846bd4c1fbf17839ae59e111c6b1c98579eda7a841412f102d6621ec671cb"
},
"emulator-ft": {
"address": "ee82856bf20e2aa6",
"key": "f2e846bd4c1fbf17839ae59e111c6b1c98579eda7a841412f102d6621ec671cb"
},
"emulator-flowtoken": {
"address": "0ae53cb6e3f42a79",
"key": "f2e846bd4c1fbf17839ae59e111c6b1c98579eda7a841412f102d6621ec671cb"
}
},
"contracts": {
"Raffles": {
"source": "./contracts/Raffles.cdc",
"aliases": {
"testing": "0x0000000000000007"
}
},
"FungibleToken": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/FungibleToken.cdc",
"aliases": {
"emulator": "0xee82856bf20e2aa6",
"testnet": "0x9a0766d93b6608b7",
"mainnet": "0xf233dcee88fe0abe"
}
},
"MetadataViews": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/MetadataViews.cdc",
"aliases": {
"emulator": "0xf8d6e0586b0a20c7",
"testnet": "0x631e88ae7f1d7c20",
"mainnet": "0x1d7e57aa55817448"
}
},
"FungibleTokenMetadataViews": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/FungibleTokenMetadataViews.cdc",
"aliases": {
"emulator": "0xee82856bf20e2aa6",
"testnet": "0x9a0766d93b6608b7",
"mainnet": "0xf233dcee88fe0abe"
}
},
"ViewResolver": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/ViewResolver.cdc",
"aliases": {
"emulator": "0xf8d6e0586b0a20c7",
"testnet": "0x631e88ae7f1d7c20",
"mainnet": "0x1d7e57aa55817448"
}
},
"NonFungibleToken": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/NonFungibleToken.cdc",
"aliases": {
"emulator": "0xf8d6e0586b0a20c7",
"testnet": "0x631e88ae7f1d7c20",
"mainnet": "0x1d7e57aa55817448"
}
},
"FlowToken": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/FlowToken.cdc",
"aliases": {
"emulator": "0x0ae53cb6e3f42a79",
"testnet": "0x7e60df042a9c0868",
"mainnet": "0x1654653399040a61"
}
},
"FindViews": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/find/FindViews.cdc",
"aliases": {
"emulator": "0xf8d6e0586b0a20c7",
"mainnet": "0x097bafa4e0b48eef",
"testnet": "0x35717efbbce11c74",
"testing": "0x0000000000000005"
}
},
"FLOAT": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/emerald-city/FLOAT.cdc",
"aliases": {
"emulator": "0xf8d6e0586b0a20c7",
"mainnet": "0x2d4c3caffbeab845",
"testnet": "0x4d47bf3ce5e4393f",
"testing": "0x0000000000000005"
}
}
},
"deployments": {
"emulator": {
"emulator-account": [
"MetadataViews",
"ViewResolver",
"NonFungibleToken",
"Raffles"
],
"emulator-ft": [
"FungibleToken",
"FungibleTokenMetadataViews"
],
"emulator-flowtoken": [
"FlowToken"
]
}
}
}
46 changes: 46 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@flowtyio/flow-contracts": "^0.0.18"
}
}
5 changes: 5 additions & 0 deletions run-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

set -e

flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" test/*_tests.cdc
6 changes: 6 additions & 0 deletions scripts/borrow_manager.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import "Raffles"

pub fun main(addr: Address) {
getAccount(addr).getCapability<&Raffles.Manager{Raffles.ManagerPublic}>(Raffles.ManagerPublicPath).borrow()
?? panic("unable to borrow manager")
}
16 changes: 16 additions & 0 deletions test/Raffles_tests.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Test
import "test_helpers.cdc"

import "Raffles"


pub fun setup() {
let err = Test.deployContract(name: "Raffles", path: "../contracts/Raffles.cdc", arguments: [])
Test.expect(err, Test.beNil())
}

pub fun setupManager() {
let acct = Test.createAccount()
txExecutor("setup_manager", [acct], [], nil)
scriptExecutor("borrow_manager.cdc", [acct.address])
}
Loading