forked from FlowFans/web3jam-2022-summer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
unknown
committed
Aug 10, 2022
1 parent
e90542a
commit 5e0d15b
Showing
5 changed files
with
436 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
 | ||
|
||
## 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 not shown.
277 changes: 277 additions & 0 deletions
277
submissions/issue-22/src/cadence/contracts/WorkDaoNFT.cdc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
} |
Oops, something went wrong.