Skip to content

Commit

Permalink
add submission FlowFans#22
Browse files Browse the repository at this point in the history
  • Loading branch information
unknown committed Aug 10, 2022
1 parent e90542a commit 5e0d15b
Show file tree
Hide file tree
Showing 5 changed files with 436 additions and 0 deletions.
77 changes: 77 additions & 0 deletions submissions/issue-22/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Project Name
### Focus

## Track

- [x] NFT x DAO/Tools
- [ ] NFT x Game/Entertainment
- [ ] NFT x Life/Metaverse

## Description

- WorkDAO hopes to help more Web2 users to learn the operation of Web3 and track knowledge in a faster and simpler way, and be able to participate in Web3 projects to become a truly professional builder, the first step we hope to achieve is to do the rabbit hole of Flow ecology, aiming to help Web2 users to be able to conveniently achieve Flow ecology Project registration and interaction, such as: Increment, flowns, MatrixMarket and other projects to use and trade, in the operation can also achieve the interaction of the project, to achieve the expectations of the future access to airdrop, the first step is also the most important feature we want to launch in this hackathon.

### Problem statement


<!--
Please describe the following
- Target audience
- Evidence for the need
-->
- Target audience
WorkDAO hopes to help more Web2 users to learn Web3 operations and track knowledge in a quicker and easier way, and to become a truly professional builder by participating in Web3 projects.

- Evidence for the need
1. China is a big country with a population of 1.4 billion, and mobile Internet users have reached everyone.
1. From 2021 onwards, Chinese Internet companies will start a wave of layoffs from online education to games, and even companies such as New Oriental (the first adult education company listed on NASDAQ in China) have almost completely changed their directions/path.
2. The number of graduates in China in 2022 is 10.76 million, And jobs cannot be fully in-taken, creates a huge gap between supply and demand


### Proposed solution

<!--
Please describe the following, including but not limited to:
- Product Introduction
- Product Logo (Optional)
- Technical architecture
- Operational strategy
-->
- Product Introduction: The first step to achieve the function of helping Web2 users trade and product learning is similar to the rabbit hole (Eth ecological project), we will connect some projects of Flow ecology with WorkDAO and achieve the function of receiving Float after users complete the interaction.

- Product Logo (Optional)
![logo](http://zhilu.space:90/assets/img/logo.0d8ff8a0.png)

## What was done during Web3 Jam

<!-- Please list the features and docs you achieved during the event -->
<!-- Please list the features and docs you achieved during the event -->

*Cadence Contract*
- [x] NFT smart contracts, including NFT generation, mint.

*Client end*
- [x] UI design
- [x] Web app basic function development
- [x] FCL integrate

> Delivery Meterials
- [Source Code](./src/), deployed to Testnet address: 0x49c260d74472cfad
<!-- Optional -->
- [Pitch Deck](./docs/deck.pdf) <!-- or using online documentation url / ipfs url -->
- [Work Dao Demo Site](http://zhilu.space:90/home) <!-- or using online documentation url / ipfs url -->

## Additional information

<!-- More information you want the judges to see -->
### Team

| Name | Role | Bio | Contact |
| --------- | ------------------- | ------------ | ------------------------- |
| Start | Designer | Flow China community ambassador, InverseDAO, ZorooDAO, 321DAO core members, is currently coordinating the creation of the book "zero-based digging into Web3", is expected to be released to the market in August or September | bookdao9527 |
| 叁肆 | Designer | Serial entrepreneur, Builder @Buidler DAO, Coding artist, UX, PM, ex Game designer of tencent | twitter@0xWindyLee |
| lansane | Full-Stack Engineer | Software architect,ten years of software development experience | ... |
| Li Yuanba | Full-Stack Engineer | entrepreneur, full-stack engineer, entered the cryptocurrency industry in 2017, and took the technical development course of "Building a Blockchain Quantitative Trading Platform from Scratch" | [email protected] |
| Hunter | Full-Stack Engineer | Blockchain practitioner, quantitative trading enthusiast, senior derivatives trader, senior secondary market trader, full-stack engineer, python developer | [email protected] |
Empty file.
Binary file added submissions/issue-22/docs/deck.pdf
Binary file not shown.
277 changes: 277 additions & 0 deletions submissions/issue-22/src/cadence/contracts/WorkDaoNFT.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
import NonFungibleToken, MetadataViews from 0x631e88ae7f1d7c20


access(all) contract WorkDaoNFT : NonFungibleToken {

pub var totalSupply: UInt64

pub event ContractInitialized()
pub event Withdraw(id: UInt64, from: Address?)
pub event Deposit(id: UInt64, to: Address?)

pub let CollectionStoragePath: StoragePath
pub let CollectionPublicPath: PublicPath
pub let MinterStoragePath: StoragePath

pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {
pub let id: UInt64

pub let name: String
pub let description: String
pub let thumbnail: String
access(self) let royalties: [MetadataViews.Royalty]
access(self) let metadata: {String: AnyStruct}

init(
id: UInt64,
name: String,
description: String,
thumbnail: String,
royalties: [MetadataViews.Royalty],
metadata: {String: AnyStruct},
) {
self.id = id
self.name = name
self.description = description
self.thumbnail = thumbnail
self.royalties = royalties
self.metadata = metadata
}

pub fun getViews(): [Type] {
return [
Type<MetadataViews.Display>(),
Type<MetadataViews.Royalties>(),
Type<MetadataViews.Editions>(),
Type<MetadataViews.ExternalURL>(),
Type<MetadataViews.NFTCollectionData>(),
Type<MetadataViews.NFTCollectionDisplay>(),
Type<MetadataViews.Serial>(),
Type<MetadataViews.Traits>()
]
}

pub fun resolveView(_ view: Type): AnyStruct? {
switch view {
case Type<MetadataViews.Display>():
return MetadataViews.Display(
name: self.name,
description: self.description,
thumbnail: MetadataViews.HTTPFile(
url: self.thumbnail
)
)
case Type<MetadataViews.Editions>():
// There is no max number of NFTs that can be minted from this contract
// so the max edition field value is set to nil
let editionInfo = MetadataViews.Edition(name: "WorkDao NFT Edition", number: self.id, max: nil)
let editionList: [MetadataViews.Edition] = [editionInfo]
return MetadataViews.Editions(
editionList
)
case Type<MetadataViews.Serial>():
return MetadataViews.Serial(
self.id
)
case Type<MetadataViews.Royalties>():
return MetadataViews.Royalties(
self.royalties
)
case Type<MetadataViews.ExternalURL>():
return MetadataViews.ExternalURL("https://example-nft.onflow.org/".concat(self.id.toString()))
case Type<MetadataViews.NFTCollectionData>():
return MetadataViews.NFTCollectionData(
storagePath: WorkDaoNFT.CollectionStoragePath,
publicPath: WorkDaoNFT.CollectionPublicPath,
providerPath: /private/WorkDaoNFTCollection,
publicCollection: Type<&WorkDaoNFT.Collection{WorkDaoNFT.WorkDaoNFTCollectionPublic}>(),
publicLinkedType: Type<&WorkDaoNFT.Collection{WorkDaoNFT.WorkDaoNFTCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Receiver,MetadataViews.ResolverCollection}>(),
providerLinkedType: Type<&WorkDaoNFT.Collection{WorkDaoNFT.WorkDaoNFTCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Provider,MetadataViews.ResolverCollection}>(),
createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
return <-WorkDaoNFT.createEmptyCollection()
})
)
case Type<MetadataViews.NFTCollectionDisplay>():
let media = MetadataViews.Media(
file: MetadataViews.HTTPFile(
url: "https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg"
),
mediaType: "image/svg+xml"
)
return MetadataViews.NFTCollectionDisplay(
name: "The Example Collection",
description: "This collection is used as an example to help you develop your next Flow NFT.",
externalURL: MetadataViews.ExternalURL("https://example-nft.onflow.org"),
squareImage: media,
bannerImage: media,
socials: {
"twitter": MetadataViews.ExternalURL("https://twitter.com/flow_blockchain")
}
)
case Type<MetadataViews.Traits>():
// exclude mintedTime and foo to show other uses of Traits
let excludedTraits = ["mintedTime", "foo"]
let traitsView = MetadataViews.dictToTraits(dict: self.metadata, excludedNames: excludedTraits)

// mintedTime is a unix timestamp, we should mark it with a displayType so platforms know how to show it.
let mintedTimeTrait = MetadataViews.Trait(name: "mintedTime", value: self.metadata["mintedTime"]!, displayType: "Date", rarity: nil)
traitsView.addTrait(mintedTimeTrait)

// foo is a trait with its own rarity
let fooTraitRarity = MetadataViews.Rarity(score: 10.0, max: 100.0, description: "Common")
let fooTrait = MetadataViews.Trait(name: "foo", value: self.metadata["foo"], displayType: nil, rarity: fooTraitRarity)
traitsView.addTrait(fooTrait)

return traitsView

}
return nil
}
}

pub resource interface WorkDaoNFTCollectionPublic {
pub fun deposit(token: @NonFungibleToken.NFT)
pub fun getIDs(): [UInt64]
pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
pub fun borrowWorkDaoNFT(id: UInt64): &WorkDaoNFT.NFT? {
post {
(result == nil) || (result?.id == id):
"Cannot borrow WorkDaoNFT reference: the ID of the returned reference is incorrect"
}
}
}

pub resource Collection: WorkDaoNFTCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
// dictionary of NFT conforming tokens
// NFT is a resource type with an `UInt64` ID field
pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}

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

// withdraw removes an NFT from the collection and moves it to the caller
pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")

emit Withdraw(id: token.id, from: self.owner?.address)

return <-token
}

// deposit takes a NFT and adds it to the collections dictionary
// and adds the ID to the id array
pub fun deposit(token: @NonFungibleToken.NFT) {
let token <- token as! @WorkDaoNFT.NFT

let id: UInt64 = token.id

// add the new token to the dictionary which removes the old one
let oldToken <- self.ownedNFTs[id] <- token

emit Deposit(id: id, to: self.owner?.address)

destroy oldToken
}

// getIDs returns an array of the IDs that are in the collection
pub fun getIDs(): [UInt64] {
return self.ownedNFTs.keys
}

// borrowNFT gets a reference to an NFT in the collection
// so that the caller can read its metadata and call its methods
pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
}

pub fun borrowWorkDaoNFT(id: UInt64): &WorkDaoNFT.NFT? {
if self.ownedNFTs[id] != nil {
// Create an authorized reference to allow downcasting
let ref = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
return ref as! &WorkDaoNFT.NFT
}

return nil
}

pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
let WorkDaoNFT = nft as! &WorkDaoNFT.NFT
return WorkDaoNFT as &AnyResource{MetadataViews.Resolver}
}

destroy() {
destroy self.ownedNFTs
}
}

// public function that anyone can call to create a new empty collection
pub fun createEmptyCollection(): @NonFungibleToken.Collection {
return <- create Collection()
}

// Resource that an admin or something similar would own to be
// able to mint new NFTs
//
pub resource NFTMinter {

// mintNFT mints a new NFT with a new ID
// and deposit it in the recipients collection using their collection reference
pub fun mintNFT(
recipient: &{NonFungibleToken.CollectionPublic},
name: String,
royalties: [MetadataViews.Royalty],
) {
let metadata: {String: AnyStruct} = {}
let currentBlock = getCurrentBlock()
metadata["mintedBlock"] = currentBlock.height
metadata["mintedTime"] = currentBlock.timestamp
metadata["minter"] = recipient.owner!.address

// this piece of metadata will be used to show embedding rarity into a trait
metadata["project_name"] = name

// create a new NFT
var newNFT <- create NFT(
id: WorkDaoNFT.totalSupply,
name: "",
description: "proof of attendence",
thumbnail: "http://zhilu.space:90/assets/img/logo.0d8ff8a0.png",
royalties: royalties,
metadata: metadata,
)

// deposit it in the recipient's account using their reference
recipient.deposit(token: <-newNFT)

WorkDaoNFT.totalSupply = WorkDaoNFT.totalSupply + UInt64(1)
}
}

init() {
// Initialize the total supply
self.totalSupply = 0

// Set the named paths
self.CollectionStoragePath = /storage/workDaoNFTCollection
self.CollectionPublicPath = /public/workDaoNFTCollection
self.MinterStoragePath = /storage/workDaoNFTMinter

// Create a Collection resource and save it to storage
let collection <- create Collection()
self.account.save(<-collection, to: self.CollectionStoragePath)

// create a public capability for the collection
self.account.link<&WorkDaoNFT.Collection{NonFungibleToken.CollectionPublic, WorkDaoNFT.WorkDaoNFTCollectionPublic, MetadataViews.ResolverCollection}>(
self.CollectionPublicPath,
target: self.CollectionStoragePath
)

// Create a Minter resource and save it to storage
let minter <- create NFTMinter()
self.account.save(<-minter, to: self.MinterStoragePath)

emit ContractInitialized()
}
}
Loading

0 comments on commit 5e0d15b

Please sign in to comment.