Smart Contract

GreenBitcoin

A.078a8129525775dd.GreenBitcoin

Deployed

3d ago
Feb 25, 2026, 01:36:08 AM UTC

Dependents

2 imports
1import FungibleToken from 0xf233dcee88fe0abe
2import FungibleTokenMetadataViews from 0xf233dcee88fe0abe
3import MetadataViews from 0x1d7e57aa55817448
4import Toucans from 0x577a3c409c5dcb5e
5import ToucansTokens from 0x577a3c409c5dcb5e
6 
7pub contract GreenBitcoin: FungibleToken {
8
9    // The amount of tokens in existance
10    pub var totalSupply: UFix64
11    // nil if there is none
12    pub let maxSupply: UFix64?
13
14    // Paths
15    pub let VaultStoragePath: StoragePath
16    pub let ReceiverPublicPath: PublicPath
17    pub let VaultPublicPath: PublicPath
18    pub let MinterStoragePath: StoragePath
19    pub let AdministratorStoragePath: StoragePath
20
21    // Events
22    pub event TokensInitialized(initialSupply: UFix64)
23    pub event TokensWithdrawn(amount: UFix64, from: Address?)
24    pub event TokensDeposited(amount: UFix64, to: Address?)
25    pub event TokensTransferred(amount: UFix64, from: Address, to: Address)
26    pub event TokensMinted(amount: UFix64)
27    pub event TokensBurned(amount: UFix64)
28
29    pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance, MetadataViews.Resolver {
30        pub var balance: UFix64
31
32        pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
33            self.balance = self.balance - amount
34            emit TokensWithdrawn(amount: amount, from: self.owner?.address)
35
36            if let owner: Address = self.owner?.address {
37                GreenBitcoin.setBalance(address: owner, balance: self.balance)
38            }
39            return <- create Vault(balance: amount)
40        }
41
42        pub fun deposit(from: @FungibleToken.Vault) {
43            let vault: @Vault <- from as! @Vault
44            self.balance = self.balance + vault.balance
45            emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
46            
47            // We set the balance to 0.0 here so that it doesn't
48            // decrease the totalSupply in the `destroy` function.
49            vault.balance = 0.0
50            destroy vault
51
52            if let owner: Address = self.owner?.address {
53                GreenBitcoin.setBalance(address: owner, balance: self.balance)
54            }
55        }
56
57        pub fun getViews(): [Type]{
58            return [Type<FungibleTokenMetadataViews.FTView>(),
59                    Type<FungibleTokenMetadataViews.FTDisplay>(),
60                    Type<FungibleTokenMetadataViews.FTVaultData>()]
61        }
62
63        pub fun resolveView(_ view: Type): AnyStruct? {
64            switch view {
65                case Type<FungibleTokenMetadataViews.FTView>():
66                    return FungibleTokenMetadataViews.FTView(
67                        ftDisplay: self.resolveView(Type<FungibleTokenMetadataViews.FTDisplay>()) as! FungibleTokenMetadataViews.FTDisplay?,
68                        ftVaultData: self.resolveView(Type<FungibleTokenMetadataViews.FTVaultData>()) as! FungibleTokenMetadataViews.FTVaultData?
69                    )
70                case Type<FungibleTokenMetadataViews.FTDisplay>():
71                    let media = MetadataViews.Media(
72                            file: MetadataViews.HTTPFile(
73                            url: "https://nftstorage.link/ipfs/bafkreigglohoo25a4zqqf6qauofnkaufoz3g7g4huijphy3jwhyyzbpnxa"
74                        ),
75                        mediaType: "image"
76                    )
77                    let medias = MetadataViews.Medias([media])
78                    return FungibleTokenMetadataViews.FTDisplay(
79                        name: "Green Bitcoin",
80                        symbol: "GBTC",
81                        description: "Every blockchain deserves a Bitcoin, and with Green Bitcoin, we aim to provide the long-awaited stability that users deserve.In a world filled with digital transactions and innovation, cryptocurrencies have revolutionized the way we store and exchange value. Blockchain technology has brought unprecedented levels of decentralization and security, but it is not without challenges.Green Bitcoin takes it a step further by focusing on sustainability and ecological responsibility. We recognize that the success of a cryptocurrency should not only be measured in financial gains but also in its impact on the environment. Therefore, we strive to create a green and sustainable Bitcoin, utilizing energy-efficient mining processes and renewable energy sources.With Green Bitcoin, we want to bestow the long-awaited stability upon users. We understand the need for stability and reliability in the cryptocurrency market. By combining a solid technological foundation, green mining practices, and a passionate community, we aim to provide a cryptocurrency that not only preserves value but also maximizes positive environmental impact.Join the Green Bitcoin movement and experience a new dimension of cryptocurrency. Together, we can pave the way towards a more sustainable and stable future.",
82                        externalURL: MetadataViews.ExternalURL(""),
83                        logos: medias,
84                        socials: {
85                            "twitter": MetadataViews.ExternalURL(""),
86                            "discord": MetadataViews.ExternalURL("https://discord.gg/vY8pK9x8")
87                        }
88                    )
89                case Type<FungibleTokenMetadataViews.FTVaultData>():
90                    return FungibleTokenMetadataViews.FTVaultData(
91                        storagePath: GreenBitcoin.VaultStoragePath,
92                        receiverPath: GreenBitcoin.ReceiverPublicPath,
93                        metadataPath: GreenBitcoin.VaultPublicPath,
94                        providerPath: /private/GreenBitcoinVault,
95                        receiverLinkedType: Type<&Vault{FungibleToken.Receiver}>(),
96                        metadataLinkedType: Type<&Vault{FungibleToken.Balance, MetadataViews.Resolver}>(),
97                        providerLinkedType: Type<&Vault{FungibleToken.Provider}>(),
98                        createEmptyVaultFunction: (fun (): @Vault {
99                            return <- GreenBitcoin.createEmptyVault()
100                        })
101                    )
102            }
103            return nil
104        }
105  
106        init(balance: UFix64) {
107            self.balance = balance
108        }
109
110        destroy() {
111            emit TokensBurned(amount: self.balance)
112            GreenBitcoin.totalSupply = GreenBitcoin.totalSupply - self.balance
113        }
114    }
115
116    pub fun createEmptyVault(): @Vault {
117        return <- create Vault(balance: 0.0)
118    }
119
120    pub resource Minter: Toucans.Minter {
121        pub fun mint(amount: UFix64): @Vault {
122            post {
123                GreenBitcoin.maxSupply == nil || GreenBitcoin.totalSupply <= GreenBitcoin.maxSupply!: 
124                    "Exceeded the max supply of tokens allowd."
125            }
126            GreenBitcoin.totalSupply = GreenBitcoin.totalSupply + amount
127            emit TokensMinted(amount: amount)
128            return <- create Vault(balance: amount)
129        }
130    }
131
132    // We follow this pattern of storage
133    // so the (potentially) huge dictionary 
134    // isn't loaded when the contract is imported
135    pub resource Administrator {
136        // This is an experimental index and should
137        // not be used for anything official
138        // or monetary related
139        access(self) let balances: {Address: UFix64}
140
141        access(contract) fun setBalance(address: Address, balance: UFix64) {
142            self.balances[address] = balance
143        }
144
145        pub fun getBalance(address: Address): UFix64 {
146            return self.balances[address] ?? 0.0
147        }
148
149        pub fun getBalances(): {Address: UFix64} {
150            return self.balances
151        }
152
153        init() {
154            self.balances = {}
155        }
156    }
157
158    access(contract) fun setBalance(address: Address, balance: UFix64) {
159        let admin: &Administrator = self.account.borrow<&Administrator>(from: self.AdministratorStoragePath)!
160        admin.setBalance(address: address, balance: balance)
161    }
162
163    pub fun getBalance(address: Address): UFix64 {
164        let admin: &Administrator = self.account.borrow<&Administrator>(from: self.AdministratorStoragePath)!
165        return admin.getBalance(address: address)
166    }
167
168    pub fun getBalances(): {Address: UFix64} {
169        let admin: &Administrator = self.account.borrow<&Administrator>(from: self.AdministratorStoragePath)!
170        return admin.getBalances()
171    }
172
173    init(
174      _paymentTokenInfo: ToucansTokens.TokenInfo,
175      _editDelay: UFix64,
176      _minting: Bool,
177      _initialTreasurySupply: UFix64,
178      _maxSupply: UFix64?,
179      _extra: {String: AnyStruct}
180    ) {
181
182      // Contract Variables
183      self.totalSupply = 0.0
184      self.maxSupply = _maxSupply
185
186      // Paths
187      self.VaultStoragePath = /storage/GreenBitcoinVault
188      self.ReceiverPublicPath = /public/GreenBitcoinReceiver
189      self.VaultPublicPath = /public/GreenBitcoinMetadata
190      self.MinterStoragePath = /storage/GreenBitcoinMinter
191      self.AdministratorStoragePath = /storage/GreenBitcoinAdmin
192 
193      // Admin Setup
194      let vault <- create Vault(balance: self.totalSupply)
195      self.account.save(<- vault, to: self.VaultStoragePath)
196
197      self.account.link<&Vault{FungibleToken.Receiver}>(
198          self.ReceiverPublicPath,
199          target: self.VaultStoragePath
200      )
201
202      self.account.link<&Vault{FungibleToken.Balance, MetadataViews.Resolver}>(
203          self.VaultPublicPath,
204          target: self.VaultStoragePath
205      )
206
207      if self.account.borrow<&Toucans.Collection>(from: Toucans.CollectionStoragePath) == nil {
208        self.account.save(<- Toucans.createCollection(), to: Toucans.CollectionStoragePath)
209        self.account.link<&Toucans.Collection{Toucans.CollectionPublic}>(Toucans.CollectionPublicPath, target: Toucans.CollectionStoragePath)
210      }
211
212      let toucansProjectCollection = self.account.borrow<&Toucans.Collection>(from: Toucans.CollectionStoragePath)!
213      toucansProjectCollection.createProject(
214        projectTokenInfo: ToucansTokens.TokenInfo("GreenBitcoin", self.account.address, "GBTC", self.ReceiverPublicPath, self.VaultPublicPath, self.VaultStoragePath), 
215        paymentTokenInfo: _paymentTokenInfo, 
216        minter: <- create Minter(), 
217        editDelay: _editDelay,
218        minting: _minting,
219        initialTreasurySupply: _initialTreasurySupply,
220        extra: _extra
221      )
222
223      self.account.save(<- create Administrator(), to: self.AdministratorStoragePath)
224
225      // Events
226      emit TokensInitialized(initialSupply: self.totalSupply)
227    }
228}
229