rubysol-contracts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/Manifest.txt +14 -0
- data/README.md +315 -0
- data/Rakefile +29 -0
- data/lib/rubysol/contracts/erc20.rb +77 -0
- data/lib/rubysol/contracts/erc20_liquidity_pool.rb +84 -0
- data/lib/rubysol/contracts/erc721.rb +121 -0
- data/lib/rubysol/contracts/ether_erc20_bridge.rb +54 -0
- data/lib/rubysol/contracts/ethscription_erc20_bridge.rb +119 -0
- data/lib/rubysol/contracts/generative_erc721.rb +93 -0
- data/lib/rubysol/contracts/open_edition_erc721.rb +54 -0
- data/lib/rubysol/contracts/public_mint_erc20.rb +37 -0
- data/lib/rubysol/contracts/version.rb +23 -0
- data/lib/rubysol/contracts.rb +18 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 93eaae4a1c50deb7cd758c3d4722586ae4db0043658ff5f67c4e3511f1c39067
|
4
|
+
data.tar.gz: 5abc50f516b527db09d6b88d8d1b2ecdcb7813f60149bea0eacf674e627b767d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ed4147e02ef81e836a395d62d3bdebf85badb296b51015588141c1f0f0ad8206fa70c689856c5ecce70d8d8abc0ed656d33307a878ef5986f1e3f72124e2d57f
|
7
|
+
data.tar.gz: a9772883af9fb960c6771711274ae79d94715609c4bdf2ed8926cdde93330e10b9bfee5adbd629a883480ca05bb204043104e58361d6f98f2eb02c5f0c77b348
|
data/CHANGELOG.md
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
CHANGELOG.md
|
2
|
+
Manifest.txt
|
3
|
+
README.md
|
4
|
+
Rakefile
|
5
|
+
lib/rubysol/contracts.rb
|
6
|
+
lib/rubysol/contracts/erc20.rb
|
7
|
+
lib/rubysol/contracts/erc20_liquidity_pool.rb
|
8
|
+
lib/rubysol/contracts/erc721.rb
|
9
|
+
lib/rubysol/contracts/ether_erc20_bridge.rb
|
10
|
+
lib/rubysol/contracts/ethscription_erc20_bridge.rb
|
11
|
+
lib/rubysol/contracts/generative_erc721.rb
|
12
|
+
lib/rubysol/contracts/open_edition_erc721.rb
|
13
|
+
lib/rubysol/contracts/public_mint_erc20.rb
|
14
|
+
lib/rubysol/contracts/version.rb
|
data/README.md
ADDED
@@ -0,0 +1,315 @@
|
|
1
|
+
# Rubysol Contracts
|
2
|
+
|
3
|
+
rubysol-contracts - standard contracts (incl. erc20, erc721, etc) for ruby for layer 1 (l1) with "off-chain" indexer
|
4
|
+
|
5
|
+
* home :: [github.com/s6ruby/rubidity](https://github.com/s6ruby/rubidity)
|
6
|
+
* bugs :: [github.com/s6ruby/rubidity/issues](https://github.com/s6ruby/rubidity/issues)
|
7
|
+
* gem :: [rubygems.org/gems/rubysol-contracts](https://rubygems.org/gems/rubysol-contracts)
|
8
|
+
* rdoc :: [rubydoc.info/gems/rubysol-contracts](http://rubydoc.info/gems/rubysol-contracts)
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
## What's Solidity?! What's Rubidity?! What's Rubysol?!
|
14
|
+
|
15
|
+
See [**Solidity - Contract Application Binary Interface (ABI) Specification** »](https://docs.soliditylang.org/en/latest/abi-spec.html)
|
16
|
+
|
17
|
+
See [**Rubidity - Ruby for Layer 1 (L1) Contracts / Protocols with "Off-Chain" Indexer** »](https://github.com/s6ruby/rubidity)
|
18
|
+
|
19
|
+
See [**Rubysol - Ruby for Layer 1 (L1) Contracts / Protocols with "Off-Chain" Indexer** »](https://github.com/s6ruby/rubidity/tree/master/rubysol)
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
Let's try the PublicMintERC20 contract...
|
27
|
+
|
28
|
+
<details>
|
29
|
+
<summary markdown="1">Show Source</summary>
|
30
|
+
|
31
|
+
[contracts/public_mint_erc20.rb](lib/rubysol/contracts/public_mint_erc20.rb):
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
class PublicMintERC20 < ERC20
|
35
|
+
|
36
|
+
storage maxSupply: UInt,
|
37
|
+
perMintLimit: UInt
|
38
|
+
|
39
|
+
sig [String, String, UInt, UInt, UInt]
|
40
|
+
def constructor(
|
41
|
+
name:,
|
42
|
+
symbol:,
|
43
|
+
maxSupply:,
|
44
|
+
perMintLimit:,
|
45
|
+
decimals:
|
46
|
+
)
|
47
|
+
super( name: name,
|
48
|
+
symbol: symbol,
|
49
|
+
decimals: decimals)
|
50
|
+
|
51
|
+
@maxSupply = maxSupply
|
52
|
+
@perMintLimit = perMintLimit
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
sig [UInt]
|
57
|
+
def mint( amount: )
|
58
|
+
assert(amount > 0, 'Amount must be positive')
|
59
|
+
assert(amount <= @perMintLimit, 'Exceeded mint limit')
|
60
|
+
|
61
|
+
assert( @totalSupply + amount <= @maxSupply, 'Exceeded max supply')
|
62
|
+
|
63
|
+
_mint(to: msg.sender, amount: amount)
|
64
|
+
end
|
65
|
+
|
66
|
+
sig [Address, UInt]
|
67
|
+
def airdrop( to:, amount: )
|
68
|
+
assert(amount > 0, 'Amount must be positive')
|
69
|
+
assert(amount <= @perMintLimit, 'Exceeded mint limit')
|
70
|
+
|
71
|
+
assert(@totalSupply + amount <= @maxSupply, 'Exceeded max supply')
|
72
|
+
|
73
|
+
_mint(to: to, amount: amount)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
</details>
|
79
|
+
|
80
|
+
that builds on the ERC20 (base) contract.
|
81
|
+
|
82
|
+
<details>
|
83
|
+
<summary markdown="1">Show Source</summary>
|
84
|
+
|
85
|
+
[contracts/erc20.rb](lib/rubysol/contracts/erc20.rb):
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class ERC20 < Contract
|
89
|
+
|
90
|
+
event :Transfer, from: Address,
|
91
|
+
to: Address,
|
92
|
+
amount: UInt
|
93
|
+
event :Approval, owner: Address,
|
94
|
+
spender: Address,
|
95
|
+
amount: UInt
|
96
|
+
|
97
|
+
storage name: String,
|
98
|
+
symbol: String,
|
99
|
+
decimals: UInt,
|
100
|
+
totalSupply: UInt,
|
101
|
+
balanceOf: mapping( Address, UInt ),
|
102
|
+
allowance: mapping( Address, mapping( Address, UInt ))
|
103
|
+
|
104
|
+
|
105
|
+
sig [String, String, UInt]
|
106
|
+
def constructor(name:,
|
107
|
+
symbol:,
|
108
|
+
decimals:)
|
109
|
+
@name = name
|
110
|
+
@symbol = symbol
|
111
|
+
@decimals = decimals
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
sig [Address, UInt], returns: Bool
|
116
|
+
def approve( spender:,
|
117
|
+
amount: )
|
118
|
+
@allowance[msg.sender][spender] = amount
|
119
|
+
|
120
|
+
log Approval, owner: msg.sender, spender: spender, amount: amount
|
121
|
+
|
122
|
+
true
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
sig [Address, UInt], returns: Bool
|
127
|
+
def decreaseAllowanceUntilZero( spender:,
|
128
|
+
difference: )
|
129
|
+
allowed = @allowance[msg.sender][spender]
|
130
|
+
|
131
|
+
newAllowed = allowed > difference ? allowed - difference : 0
|
132
|
+
|
133
|
+
approve(spender: spender, amount: newAllowed)
|
134
|
+
|
135
|
+
true
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
sig [Address, UInt], returns: Bool
|
140
|
+
def transfer( to:,
|
141
|
+
amount: )
|
142
|
+
assert @balanceOf[msg.sender] >= amount, 'Insufficient balance'
|
143
|
+
|
144
|
+
@balanceOf[msg.sender] -= amount
|
145
|
+
@balanceOf[to] += amount
|
146
|
+
|
147
|
+
log Transfer, from: msg.sender, to: to, amount: amount
|
148
|
+
|
149
|
+
true
|
150
|
+
end
|
151
|
+
|
152
|
+
sig [Address, Address, UInt], returns: Bool
|
153
|
+
def transferFrom(
|
154
|
+
from:,
|
155
|
+
to:,
|
156
|
+
amount:)
|
157
|
+
allowed = @allowance[from][msg.sender]
|
158
|
+
|
159
|
+
assert @balanceOf[from] >= amount, 'Insufficient balance'
|
160
|
+
assert allowed >= amount, 'Insufficient allowance'
|
161
|
+
|
162
|
+
@allowance[from][msg.sender] = allowed - amount
|
163
|
+
|
164
|
+
@balanceOf[from] -= amount
|
165
|
+
@balanceOf[to] += amount
|
166
|
+
|
167
|
+
log Transfer, from: from, to: to, amount: amount
|
168
|
+
|
169
|
+
true
|
170
|
+
end
|
171
|
+
|
172
|
+
sig [Address, UInt]
|
173
|
+
def _mint( to:,
|
174
|
+
amount: )
|
175
|
+
@totalSupply += amount
|
176
|
+
@balanceOf[to] += amount
|
177
|
+
|
178
|
+
log Transfer, from: address(0), to: to, amount: amount
|
179
|
+
end
|
180
|
+
|
181
|
+
sig [Address, UInt]
|
182
|
+
def _burn( from:,
|
183
|
+
amount: )
|
184
|
+
@balanceOf[from] -= amount
|
185
|
+
@totalSupply -= amount
|
186
|
+
|
187
|
+
log Transfer, from: from, to: address(0), amount: amount
|
188
|
+
end
|
189
|
+
end
|
190
|
+
```
|
191
|
+
|
192
|
+
</details>
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
Let's go.
|
197
|
+
|
198
|
+
``` ruby
|
199
|
+
require 'rubysol/contracts'
|
200
|
+
|
201
|
+
contract = PublicMintERC20.construct(
|
202
|
+
name: 'My Fun Token', # String,
|
203
|
+
symbol: 'FUN', # String,
|
204
|
+
maxSupply: 21000000, # UInt,
|
205
|
+
perMintLimit: 1000, # UInt,
|
206
|
+
decimals: 18, # UInt
|
207
|
+
)
|
208
|
+
|
209
|
+
|
210
|
+
contract.serialize
|
211
|
+
# {:name=>"My Fun Token",
|
212
|
+
# :symbol=>"FUN",
|
213
|
+
# :decimals=>18,
|
214
|
+
# :totalSupply=>0,
|
215
|
+
# :balanceOf=>{},
|
216
|
+
# :allowance=>{},
|
217
|
+
# :maxSupply=>21000000,
|
218
|
+
# :perMintLimit=>1000}
|
219
|
+
|
220
|
+
alice = '0x'+'a'*40 # e.g. '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
221
|
+
bob = '0x'+'b'*40 # e.g. '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
|
222
|
+
charlie = '0x'+'c'*40 # e.g. '0xcccccccccccccccccccccccccccccccccccccccc'
|
223
|
+
|
224
|
+
|
225
|
+
# sig [UInt]
|
226
|
+
# def mint( amount: )
|
227
|
+
contract.msg.sender = alice
|
228
|
+
|
229
|
+
contract.mint( 100 )
|
230
|
+
contract.mint( 200 )
|
231
|
+
|
232
|
+
contract.msg.sender = bob
|
233
|
+
|
234
|
+
contract.mint( 300 )
|
235
|
+
contract.mint( 400 )
|
236
|
+
|
237
|
+
# sig [Address, UInt]
|
238
|
+
# def airdrop( to:, amount: )
|
239
|
+
contract.airdrop( alice, 500 )
|
240
|
+
contract.airdrop( charlie, 600 )
|
241
|
+
|
242
|
+
contract.serialize
|
243
|
+
# {:name=>"My Fun Token",
|
244
|
+
# :symbol=>"FUN",
|
245
|
+
# :decimals=>18,
|
246
|
+
# :totalSupply=>2100,
|
247
|
+
# :balanceOf=>
|
248
|
+
# {"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=>800,
|
249
|
+
# "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"=>700,
|
250
|
+
# "0xcccccccccccccccccccccccccccccccccccccccc"=>600},
|
251
|
+
# :allowance=>{},
|
252
|
+
# :maxSupply=>21000000,
|
253
|
+
# :perMintLimit=>1000}
|
254
|
+
|
255
|
+
|
256
|
+
# sig [Address, UInt], returns: Bool
|
257
|
+
# def transfer( to:, amount: )
|
258
|
+
contract.transfer( alice, 1 )
|
259
|
+
contract.transfer( charlie, 2 )
|
260
|
+
|
261
|
+
# sig [Address, UInt], returns: Bool
|
262
|
+
# def approve( spender:, amount: )
|
263
|
+
contract.approve( alice, 11 )
|
264
|
+
contract.approve( charlie, 22 )
|
265
|
+
|
266
|
+
|
267
|
+
# sig [Address, Address, UInt], returns: Bool
|
268
|
+
# def transferFrom( from:, to:, amount:)
|
269
|
+
contract.msg.sender = alice
|
270
|
+
|
271
|
+
contract.approve( bob, 33 )
|
272
|
+
|
273
|
+
contract.transferFrom( bob, charlie, 3 )
|
274
|
+
contract.transferFrom( bob, alice, 4 )
|
275
|
+
|
276
|
+
contract.serialize
|
277
|
+
# {:name=>"My Fun Token",
|
278
|
+
# :symbol=>"FUN",
|
279
|
+
# :decimals=>18,
|
280
|
+
# :totalSupply=>2100,
|
281
|
+
# :balanceOf=>
|
282
|
+
# {"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=>805,
|
283
|
+
# "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"=>690,
|
284
|
+
# "0xcccccccccccccccccccccccccccccccccccccccc"=>605},
|
285
|
+
# :allowance=>
|
286
|
+
# {"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"=> {
|
287
|
+
# "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=>4,
|
288
|
+
# "0xcccccccccccccccccccccccccccccccccccccccc"=>22},
|
289
|
+
# "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=> {
|
290
|
+
# "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"=>33}},
|
291
|
+
# :maxSupply=>21000000,
|
292
|
+
# :perMintLimit=>1000}
|
293
|
+
```
|
294
|
+
|
295
|
+
And so on. That's it for now.
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
## Bonus - More Blockchain (Crypto) Tools, Libraries & Scripts In Ruby
|
300
|
+
|
301
|
+
See [**/blockchain**](https://github.com/rubycocos/blockchain)
|
302
|
+
at the ruby code commons (rubycocos) org.
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
## Questions? Comments?
|
309
|
+
|
310
|
+
Join us in the [Rubidity & Rubysol (community) discord (chat server)](https://discord.gg/3JRnDUap6y). Yes you can.
|
311
|
+
Your questions and commentary welcome.
|
312
|
+
|
313
|
+
Or post them over at the [Help & Support](https://github.com/geraldb/help) page. Thanks.
|
314
|
+
|
315
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
require './lib/rubysol/contracts/version.rb'
|
3
|
+
|
4
|
+
Hoe.spec 'rubysol-contracts' do
|
5
|
+
|
6
|
+
self.version = Rubysol::Module::Contracts::VERSION
|
7
|
+
|
8
|
+
self.summary = 'rubysol-contracts - standard contracts (incl. erc20, erc721, etc) for ruby for layer 1 (l1) with "off-chain" indexer'
|
9
|
+
self.description = summary
|
10
|
+
|
11
|
+
self.urls = { home: 'https://github.com/s6ruby/rubidity' }
|
12
|
+
|
13
|
+
self.author = 'Gerald Bauer'
|
14
|
+
self.email = 'gerald.bauer@gmail.com'
|
15
|
+
|
16
|
+
# switch extension to .markdown for gihub formatting
|
17
|
+
self.readme_file = 'README.md'
|
18
|
+
self.history_file = 'CHANGELOG.md'
|
19
|
+
|
20
|
+
self.extra_deps = [
|
21
|
+
['rubysol', '>= 0.1.0'],
|
22
|
+
]
|
23
|
+
|
24
|
+
self.licenses = ['Public Domain']
|
25
|
+
|
26
|
+
self.spec_extras = {
|
27
|
+
required_ruby_version: '>= 2.3'
|
28
|
+
}
|
29
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class ERC20 < Contract # abstract: true
|
2
|
+
|
3
|
+
event :Transfer, from: Address,
|
4
|
+
to: Address,
|
5
|
+
amount: UInt
|
6
|
+
event :Approval, owner: Address,
|
7
|
+
spender: Address,
|
8
|
+
amount: UInt
|
9
|
+
|
10
|
+
storage name: String,
|
11
|
+
symbol: String,
|
12
|
+
decimals: UInt,
|
13
|
+
totalSupply: UInt,
|
14
|
+
balanceOf: mapping( Address, UInt),
|
15
|
+
allowance: mapping( Address, mapping( Address, UInt))
|
16
|
+
|
17
|
+
sig [String, String, UInt]
|
18
|
+
def constructor(name:, symbol:, decimals:)
|
19
|
+
@name = name
|
20
|
+
@symbol = symbol
|
21
|
+
@decimals = decimals
|
22
|
+
end
|
23
|
+
|
24
|
+
sig [Address, UInt], returns: Bool
|
25
|
+
def approve( spender:, amount: )
|
26
|
+
@allowance[msg.sender][spender] = amount
|
27
|
+
|
28
|
+
log Approval, owner: msg.sender, spender: spender, amount: amount
|
29
|
+
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
sig [Address, UInt], returns: Bool
|
34
|
+
def transfer( to:, amount: )
|
35
|
+
assert @balanceOf[msg.sender] >= amount, "Insufficient balance"
|
36
|
+
|
37
|
+
@balanceOf[msg.sender] -= amount
|
38
|
+
@balanceOf[to] += amount
|
39
|
+
|
40
|
+
log Transfer, from: msg.sender, to: to, amount: amount
|
41
|
+
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
sig [Address, Address, UInt], returns: Bool
|
46
|
+
def transferFrom( from:, to:, amount: )
|
47
|
+
allowed = @allowance[from][msg.sender]
|
48
|
+
|
49
|
+
assert @balanceOf[from] >= amount, "Insufficient balance"
|
50
|
+
assert allowed >= amount, "Insufficient allowance"
|
51
|
+
|
52
|
+
@allowance[from][msg.sender] = allowed - amount
|
53
|
+
|
54
|
+
@balanceOf[from] -= amount
|
55
|
+
@balanceOf[to] += amount
|
56
|
+
|
57
|
+
log Transfer, from: from, to: to, amount: amount
|
58
|
+
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
sig [Address, UInt]
|
63
|
+
def _mint( to:, amount: )
|
64
|
+
@totalSupply += amount
|
65
|
+
@balanceOf[to] += amount
|
66
|
+
|
67
|
+
log Transfer, from: address(0), to: to, amount: amount
|
68
|
+
end
|
69
|
+
|
70
|
+
sig [Address, UInt]
|
71
|
+
def _burn( from:, amount: )
|
72
|
+
@balanceOf[from] -= amount
|
73
|
+
@totalSupply -= amount
|
74
|
+
|
75
|
+
log Transfer, from: from, to: address(0), amount: amount
|
76
|
+
end
|
77
|
+
end # class ERC20
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class ERC20LiquidityPool < Contract
|
2
|
+
|
3
|
+
storage token0: Address,
|
4
|
+
token1: Address
|
5
|
+
|
6
|
+
sig [Address, Address]
|
7
|
+
def constructor( token0:,
|
8
|
+
token1: )
|
9
|
+
@token0 = token0
|
10
|
+
@token1 = token1
|
11
|
+
end
|
12
|
+
|
13
|
+
sig [UInt, UInt]
|
14
|
+
def addLiquidity( token0Amount:,
|
15
|
+
token1Amount: )
|
16
|
+
ERC20(@token0).transferFrom(
|
17
|
+
from: msg.sender,
|
18
|
+
to: address( this ), ## note: add support for this (alias for self ??)
|
19
|
+
amount: token0Amount
|
20
|
+
)
|
21
|
+
|
22
|
+
ERC20(@token1).transferFrom(
|
23
|
+
from: msg.sender,
|
24
|
+
to: address(this),
|
25
|
+
amount: token1Amount
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
sig [], :view ### fix- support multiple, returns: [UInt, UInt]
|
31
|
+
def reserves
|
32
|
+
{
|
33
|
+
token0: ERC20(@token0).balanceOf(address(this)),
|
34
|
+
token1: ERC20(@token1).balanceOf(address(this))
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
sig [Address, Address, UInt], :view, returns: UInt
|
41
|
+
def calculateOutputAmount( inputToken:,
|
42
|
+
outputToken:,
|
43
|
+
inputAmount: )
|
44
|
+
inputReserve = ERC20(inputToken).balanceOf(address(this))
|
45
|
+
outputReserve = ERC20(outputToken).balanceOf(address(this))
|
46
|
+
|
47
|
+
((inputAmount * outputReserve) / (inputReserve + inputAmount)).to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
sig [Address, Address, UInt], returns: UInt
|
52
|
+
def swap(
|
53
|
+
inputToken:,
|
54
|
+
outputToken:,
|
55
|
+
inputAmount: )
|
56
|
+
assert [@token0, @token1].include?(inputToken), "Invalid input token"
|
57
|
+
assert [@token0, @token1].include?(outputToken), "Invalid output token"
|
58
|
+
|
59
|
+
assert inputToken != outputToken, "Input and output tokens can't be the same"
|
60
|
+
|
61
|
+
outputAmount = calculateOutputAmount(
|
62
|
+
inputToken: inputToken,
|
63
|
+
outputToken: outputToken,
|
64
|
+
inputAmount: inputAmount
|
65
|
+
)
|
66
|
+
|
67
|
+
outputReserve = ERC20(outputToken).balanceOf( address(this))
|
68
|
+
|
69
|
+
assert outputAmount <= outputReserve, "Insufficient output reserve"
|
70
|
+
|
71
|
+
ERC20(inputToken).transferFrom(
|
72
|
+
from: msg.sender,
|
73
|
+
to: dumbContractId(this),
|
74
|
+
amount: inputAmount
|
75
|
+
)
|
76
|
+
|
77
|
+
ERC20(outputToken).transfer(
|
78
|
+
msg.sender,
|
79
|
+
outputAmount
|
80
|
+
)
|
81
|
+
|
82
|
+
outputAmount
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
class ERC721 < Contract
|
2
|
+
|
3
|
+
event :Transfer, from: Address,
|
4
|
+
to: Address,
|
5
|
+
id: UInt
|
6
|
+
event :Approval, owner: Address,
|
7
|
+
spender: Address,
|
8
|
+
id: UInt
|
9
|
+
event :ApprovalForAll, owner: Address,
|
10
|
+
operator: Address,
|
11
|
+
approved: Bool
|
12
|
+
|
13
|
+
storage name: String,
|
14
|
+
symbol: String,
|
15
|
+
_ownerOf: mapping( UInt, Address ),
|
16
|
+
_balanceOf: mapping( Address, UInt ),
|
17
|
+
getApproved: mapping( UInt, Address ),
|
18
|
+
isApprovedForAll: mapping( Address, mapping( Address, Bool ))
|
19
|
+
|
20
|
+
sig [String, String]
|
21
|
+
def constructor( name:,
|
22
|
+
symbol: )
|
23
|
+
@name = name
|
24
|
+
@symbol = symbol
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
sig [ UInt ], :view, returns: Address
|
29
|
+
def ownerOf( id )
|
30
|
+
owner = @_ownerOf[id]
|
31
|
+
assert owner != address(0), "ERC721: owner query for nonexistent token"
|
32
|
+
|
33
|
+
owner
|
34
|
+
end
|
35
|
+
|
36
|
+
sig [ Address ], :view, returns: UInt
|
37
|
+
def balanceOf( owner: )
|
38
|
+
assert owner != address(0), "ERC721: balance query for nonexistent owner"
|
39
|
+
|
40
|
+
@_balanceOf[owner]
|
41
|
+
end
|
42
|
+
|
43
|
+
sig [ Address, UInt]
|
44
|
+
def approve( spender:,
|
45
|
+
id: )
|
46
|
+
owner = @_ownerOf[id]
|
47
|
+
|
48
|
+
assert msg.sender == owner || @isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"
|
49
|
+
|
50
|
+
@getApproved[id] = spender;
|
51
|
+
|
52
|
+
log Approval, owner: owner, spender: spender, id: id
|
53
|
+
end
|
54
|
+
|
55
|
+
sig [Address, Bool]
|
56
|
+
def setApprovalForAll( operator:,
|
57
|
+
approved: )
|
58
|
+
@isApprovedForAll[msg.sender][operator] = approved;
|
59
|
+
|
60
|
+
log ApprovalForAll, owner: msg.sender, operator: operator, approved: approved
|
61
|
+
end
|
62
|
+
|
63
|
+
sig [ Address, Address, UInt]
|
64
|
+
def transferFrom( from:,
|
65
|
+
to:,
|
66
|
+
id: )
|
67
|
+
assert from == @_ownerOf[id], "ERC721: transfer of token that is not own"
|
68
|
+
assert to != address(0), "ERC721: transfer to the zero address"
|
69
|
+
|
70
|
+
assert(
|
71
|
+
msg.sender == from ||
|
72
|
+
@getApproved[id] == msg.sender ||
|
73
|
+
@isApprovedForAll[from][msg.sender],
|
74
|
+
"NOT_AUTHORIZED"
|
75
|
+
)
|
76
|
+
|
77
|
+
@_balanceOf[from] -= 1
|
78
|
+
@_balanceOf[to] += 1
|
79
|
+
|
80
|
+
@_ownerOf[id] = to
|
81
|
+
|
82
|
+
@getApproved[id] = address(0)
|
83
|
+
end
|
84
|
+
|
85
|
+
sig [UInt]
|
86
|
+
def _exists( id )
|
87
|
+
@_ownerOf[id] != address(0)
|
88
|
+
end
|
89
|
+
|
90
|
+
sig [Address, UInt]
|
91
|
+
def _mint( to:,
|
92
|
+
id: )
|
93
|
+
assert to != address(0), "ERC721: mint to the zero address"
|
94
|
+
assert @_ownerOf[id] == address(0), "ERC721: token already minted"
|
95
|
+
|
96
|
+
@_balanceOf[to] += 1
|
97
|
+
|
98
|
+
@_ownerOf[id] = to
|
99
|
+
|
100
|
+
log Transfer, from: address(0), to: to, id: id
|
101
|
+
end
|
102
|
+
|
103
|
+
sig [UInt]
|
104
|
+
def _burn( id: )
|
105
|
+
owner = @_ownerOf[id]
|
106
|
+
|
107
|
+
assert owner != address(0), "ERC721: burn of nonexistent token"
|
108
|
+
|
109
|
+
@_balanceOf[owner] -= 1
|
110
|
+
|
111
|
+
@_ownerOf[id] = address(0)
|
112
|
+
|
113
|
+
@getApproved[id] = address(0)
|
114
|
+
|
115
|
+
log Transfer, from: owner, to: address(0), id: id
|
116
|
+
end
|
117
|
+
|
118
|
+
sig [UInt], :view, returns: String
|
119
|
+
def tokenURI( id: )
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class EtherERC20Bridge < ERC20
|
2
|
+
|
3
|
+
event :InitiateWithdrawal, from: Address, amount: UInt
|
4
|
+
event :WithdrawalComplete, to: Address, amount: UInt
|
5
|
+
|
6
|
+
storage trustedSmartContract: Address,
|
7
|
+
pendingWithdrawals: mapping( Address, UInt )
|
8
|
+
|
9
|
+
sig [String, String, Address]
|
10
|
+
def constructor(
|
11
|
+
name:,
|
12
|
+
symbol:,
|
13
|
+
trustedSmartContract:)
|
14
|
+
super(name: name, symbol: symbol, decimals: 18)
|
15
|
+
|
16
|
+
@trustedSmartContract = trustedSmartContract
|
17
|
+
end
|
18
|
+
|
19
|
+
sig [Address, UInt]
|
20
|
+
def bridgeIn( to:, amount: )
|
21
|
+
assert(
|
22
|
+
address(msg.sender) == @trustedSmartContract,
|
23
|
+
"Only the trusted smart contract can bridge in tokens"
|
24
|
+
)
|
25
|
+
|
26
|
+
_mint(to: to, amount: amount)
|
27
|
+
end
|
28
|
+
|
29
|
+
sig [UInt]
|
30
|
+
def bridgeOut( amount: )
|
31
|
+
_burn(from: msg.sender, amount: amount)
|
32
|
+
|
33
|
+
@pendingWithdrawals[address(msg.sender)] += amount
|
34
|
+
|
35
|
+
log InitiateWithdrawal, from: address(msg.sender), amount: amount
|
36
|
+
end
|
37
|
+
|
38
|
+
sig [Address, UInt]
|
39
|
+
def markWithdrawalComplete( to:, amount: )
|
40
|
+
assert(
|
41
|
+
address(msg.sender) == @trustedSmartContract,
|
42
|
+
'Only the trusted smart contract can mark withdrawals as complete'
|
43
|
+
)
|
44
|
+
|
45
|
+
assert(
|
46
|
+
@pendingWithdrawals[to] >= amount,
|
47
|
+
'Insufficient pending withdrawal'
|
48
|
+
)
|
49
|
+
|
50
|
+
@pendingWithdrawals[to] -= amount
|
51
|
+
|
52
|
+
log WithdrawalComplete, to: to, amount: amount
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
class EthscriptionERC20Bridge < ERC20
|
2
|
+
|
3
|
+
event :InitiateWithdrawal, from: Address, escrowedId: InscriptionId
|
4
|
+
event :WithdrawalComplete, to: Address, escrowedId: InscriptionId
|
5
|
+
|
6
|
+
storage ethscriptionsTicker: String,
|
7
|
+
ethscriptionMintAmount: UInt,
|
8
|
+
ethscriptionMaxSupply: UInt,
|
9
|
+
ethscriptionDeployId: InscriptionId,
|
10
|
+
trustedSmartContract: Address,
|
11
|
+
pendingWithdrawalEthscriptionToOwner: mapping( InscriptionId, Address ),
|
12
|
+
bridgedEthscriptionToOwner: mapping( InscriptionId, Address )
|
13
|
+
|
14
|
+
sig [String, String, Address, InscriptionId]
|
15
|
+
def constructor(
|
16
|
+
name:,
|
17
|
+
symbol:,
|
18
|
+
trustedSmartContract:,
|
19
|
+
ethscriptionDeployId:)
|
20
|
+
super(name: name, symbol: symbol, decimals: 18)
|
21
|
+
|
22
|
+
@trustedSmartContract = trustedSmartContract
|
23
|
+
@ethscriptionDeployId = ethscriptionDeployId
|
24
|
+
|
25
|
+
deploy = esc.findEthscriptionById( ethscriptionDeployId )
|
26
|
+
uri = deploy.contentUri
|
27
|
+
parsed = JSON.parse(uri.split("data:,").last)
|
28
|
+
|
29
|
+
assert(parsed['op'] == 'deploy', "Invalid ethscription deploy id")
|
30
|
+
assert(parsed['p'] == 'erc-20', "Invalid protocol")
|
31
|
+
|
32
|
+
@ethscriptionsTicker = parsed['tick']
|
33
|
+
@ethscriptionMintAmount = parsed['lim']
|
34
|
+
@ethscriptionMaxSupply = parsed['max']
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
sig [Address, InscriptionId]
|
39
|
+
def bridgeIn( to:, escrowedId: )
|
40
|
+
assert(
|
41
|
+
address(msg.sender) == @trustedSmartContract,
|
42
|
+
"Only the trusted smart contract can bridge in tokens"
|
43
|
+
)
|
44
|
+
|
45
|
+
assert(
|
46
|
+
@bridgedEthscriptionToOwner[escrowedId] == address(0),
|
47
|
+
"Ethscription already bridged in"
|
48
|
+
)
|
49
|
+
|
50
|
+
assert(
|
51
|
+
@pendingWithdrawalEthscriptionToOwner[escrowedId] == address(0),
|
52
|
+
"Ethscription withdrawal initiated"
|
53
|
+
)
|
54
|
+
|
55
|
+
ethscription = esc.findEthscriptionById(escrowedId)
|
56
|
+
uri = ethscription.contentUri
|
57
|
+
|
58
|
+
match_data = uri.match(/data:,{"p":"erc-20","op":"mint","tick":"([a-z]+)","id":"([1-9]+\d*)","amt":"([1-9]+\d*)"}/)
|
59
|
+
|
60
|
+
assert(match_data.present?, "Invalid ethscription content uri")
|
61
|
+
|
62
|
+
tick, id, amt = match_data.captures
|
63
|
+
|
64
|
+
tick = tick.cast(:string)
|
65
|
+
id = id.cast(:uint256)
|
66
|
+
amt = amt.cast(:uint256)
|
67
|
+
|
68
|
+
assert(tick == @ethscriptionsTicker, "Invalid ethscription ticker")
|
69
|
+
assert(amt == @ethscriptionMintAmount, "Invalid ethscription mint amount")
|
70
|
+
|
71
|
+
maxId = @ethscriptionMaxSupply / @ethscriptionMintAmount
|
72
|
+
|
73
|
+
assert(id > 0 && id <= maxId, "Invalid token id")
|
74
|
+
|
75
|
+
assert(
|
76
|
+
ethscription.currentOwner == @trustedSmartContract,
|
77
|
+
"Ethscription not owned by recipient. Observed owner: #{ethscription.currentOwner}, expected owner: #{@trustedSmartContract}"
|
78
|
+
)
|
79
|
+
|
80
|
+
assert(
|
81
|
+
ethscription.previousOwner == to,
|
82
|
+
"Ethscription not previously owned by to. Observed previous owner: #{ethscription.previousOwner}, expected previous owner: #{to}"
|
83
|
+
)
|
84
|
+
|
85
|
+
@bridgedEthscriptionToOwner[escrowedId] = to
|
86
|
+
_mint(to: to, amount: @ethscriptionMintAmount * (10 ** decimals))
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
sig [InscriptionId]
|
91
|
+
def bridgeOut( escrowedId )
|
92
|
+
assert( @bridgedEthscriptionToOwner[escrowedId] == address(msg.sender), "Ethscription not owned by sender")
|
93
|
+
|
94
|
+
_burn(from: msg.sender, amount: @ethscriptionMintAmount * (10 ** decimals))
|
95
|
+
|
96
|
+
@bridgedEthscriptionToOwner[escrowedId] = address(0)
|
97
|
+
@pendingWithdrawalEthscriptionToOwner[escrowedId] = address(msg.sender)
|
98
|
+
|
99
|
+
log InitiateWithdrawal, from: address(msg.sender), escrowedId: :ethscriptionId
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
sig [Address, InscriptionId]
|
104
|
+
def markWithdrawalComplete( to:, escrowedId: )
|
105
|
+
assert(
|
106
|
+
address(msg.sender) == @trustedSmartContract,
|
107
|
+
'Only the trusted smart contract can mark withdrawals as complete'
|
108
|
+
)
|
109
|
+
|
110
|
+
assert(
|
111
|
+
@pendingWithdrawalEthscriptionToOwner[escrowedId] == to,
|
112
|
+
"Withdrawal not initiated"
|
113
|
+
)
|
114
|
+
|
115
|
+
@pendingWithdrawalEthscriptionToOwner[escrowedId] = address(0)
|
116
|
+
|
117
|
+
log WithdrawalComplete, to: to, escrowedId: :ethscriptionId
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class GenerativeERC721 < ERC721
|
2
|
+
|
3
|
+
storage generativeScript: String,
|
4
|
+
tokenIdToSeed: mapping( UInt, UInt ),
|
5
|
+
totalSupply: UInt,
|
6
|
+
maxSupply: UInt,
|
7
|
+
maxPerAddress: UInt,
|
8
|
+
description: String
|
9
|
+
|
10
|
+
sig [ String, String, String, UInt, String, UInt]
|
11
|
+
def constructor(
|
12
|
+
name:,
|
13
|
+
symbol:,
|
14
|
+
generativeScript:,
|
15
|
+
maxSupply:,
|
16
|
+
description:,
|
17
|
+
maxPerAddress: )
|
18
|
+
super(name: name, symbol: symbol)
|
19
|
+
|
20
|
+
@maxSupply = maxSupply
|
21
|
+
@maxPerAddress = maxPerAddress
|
22
|
+
@description = description
|
23
|
+
@generativeScript = generativeScript
|
24
|
+
end
|
25
|
+
|
26
|
+
sig [UInt]
|
27
|
+
def mint( amount )
|
28
|
+
assert(amount > 0, 'Amount must be positive')
|
29
|
+
assert(amount + @_balanceOf[msg.sender] <= @maxPerAddress, 'Exceeded mint limit')
|
30
|
+
assert(amount + @totalSupply <= @maxSupply, 'Exceeded max supply')
|
31
|
+
|
32
|
+
hash = block.blockhash(block.number).cast(:uint256) % (2 ** 48)
|
33
|
+
|
34
|
+
amount.times do |id|
|
35
|
+
tokenId = @totalSupply + id
|
36
|
+
seed = hash + tokenId
|
37
|
+
|
38
|
+
@tokenIdToSeed[tokenId] = seed
|
39
|
+
|
40
|
+
_mint(to: msg.sender, id: tokenId)
|
41
|
+
end
|
42
|
+
|
43
|
+
@totalSupply += amount
|
44
|
+
end
|
45
|
+
|
46
|
+
sig [UInt], :view, returns: String
|
47
|
+
def tokenURI( id )
|
48
|
+
assert( _exists(id: id), 'ERC721Metadata: URI query for nonexistent token')
|
49
|
+
|
50
|
+
html = getHTML(seed: @tokenIdToSeed[id])
|
51
|
+
|
52
|
+
html_as_base_64_data_uri = "data:text/html;base64,#{Base64.strict_encode64(html)}"
|
53
|
+
|
54
|
+
json_data = {
|
55
|
+
name: "#{@name} ##{string(id)}",
|
56
|
+
description: @description,
|
57
|
+
animation_url: html_as_base_64_data_uri,
|
58
|
+
}.to_json
|
59
|
+
|
60
|
+
"data:application/json,#{json_data}"
|
61
|
+
end
|
62
|
+
|
63
|
+
sig [UInt], :view, returns: String
|
64
|
+
def getHTML( seed )
|
65
|
+
%{<!DOCTYPE html>
|
66
|
+
<html>
|
67
|
+
<head>
|
68
|
+
<style>
|
69
|
+
body,
|
70
|
+
html {
|
71
|
+
width: 100%;
|
72
|
+
height: 100%;
|
73
|
+
margin: 0;
|
74
|
+
padding: 0;
|
75
|
+
overflow: hidden;
|
76
|
+
display: block;
|
77
|
+
}
|
78
|
+
|
79
|
+
#canvas {
|
80
|
+
position: absolute;
|
81
|
+
}
|
82
|
+
</style>
|
83
|
+
</head>
|
84
|
+
<body>
|
85
|
+
<canvas id="canvas"></canvas>
|
86
|
+
</body>
|
87
|
+
<script>
|
88
|
+
window.SEED = #{string(seed)};
|
89
|
+
#{@generativeScript}
|
90
|
+
</script>
|
91
|
+
</html>}
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class OpenEditionERC721 < ERC721
|
2
|
+
|
3
|
+
storage contentURI: String,
|
4
|
+
maxPerAddress: UInt,
|
5
|
+
totalSupply: UInt,
|
6
|
+
description: String,
|
7
|
+
mintStart: Timestamp,
|
8
|
+
mintEnd: Timestamp
|
9
|
+
|
10
|
+
sig [String, String, String, UInt, String, Timestamp, Timestamp]
|
11
|
+
def constructor(
|
12
|
+
name:,
|
13
|
+
symbol:,
|
14
|
+
contentURI:,
|
15
|
+
maxPerAddress:,
|
16
|
+
description:,
|
17
|
+
mintStart:,
|
18
|
+
mintEnd: )
|
19
|
+
super(name: name, symbol: symbol)
|
20
|
+
|
21
|
+
@maxPerAddress = maxPerAddress
|
22
|
+
@description = description
|
23
|
+
@contentURI = contentURI
|
24
|
+
@mintStart = mintStart
|
25
|
+
@mintEnd = mintEnd
|
26
|
+
end
|
27
|
+
|
28
|
+
sig [UInt]
|
29
|
+
def mint( amount: )
|
30
|
+
assert(amount > 0, 'Amount must be positive')
|
31
|
+
assert(amount + @_balanceOf[msg.sender] <= @maxPerAddress, 'Exceeded mint limit')
|
32
|
+
assert(block.timestamp >= @mintStart, 'Minting has not started')
|
33
|
+
assert(block.timestamp < @mintEnd, 'Minting has ended')
|
34
|
+
|
35
|
+
amount.times do |id|
|
36
|
+
_mint(to: msg.sender, id: @totalSupply + id)
|
37
|
+
end
|
38
|
+
|
39
|
+
@totalSupply += amount
|
40
|
+
end
|
41
|
+
|
42
|
+
sig [UInt], :view, returns: String
|
43
|
+
def tokenURI( id: )
|
44
|
+
assert(_exists(id: id), 'ERC721Metadata: URI query for nonexistent token')
|
45
|
+
|
46
|
+
json_data = {
|
47
|
+
name: "#{@name} ##{string(id)}",
|
48
|
+
description: @description,
|
49
|
+
image: @contentURI,
|
50
|
+
}.to_json
|
51
|
+
|
52
|
+
"data:application/json,#{json_data}"
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
class PublicMintERC20 < ERC20
|
3
|
+
|
4
|
+
storage maxSupply: UInt,
|
5
|
+
perMintLimit: UInt
|
6
|
+
|
7
|
+
sig [String, String, UInt, UInt, UInt]
|
8
|
+
def constructor(
|
9
|
+
name:,
|
10
|
+
symbol:,
|
11
|
+
maxSupply:,
|
12
|
+
perMintLimit:,
|
13
|
+
decimals:
|
14
|
+
)
|
15
|
+
super( name: name, symbol: symbol, decimals: decimals )
|
16
|
+
@maxSupply = maxSupply
|
17
|
+
@perMintLimit = perMintLimit
|
18
|
+
end
|
19
|
+
|
20
|
+
sig [UInt]
|
21
|
+
def mint( amount: )
|
22
|
+
assert amount > 0, 'Amount must be positive'
|
23
|
+
assert amount <= @perMintLimit, 'Exceeded mint limit'
|
24
|
+
assert @totalSupply + amount <= @maxSupply, 'Exceeded max supply'
|
25
|
+
|
26
|
+
_mint( to: msg.sender, amount: amount )
|
27
|
+
end
|
28
|
+
|
29
|
+
sig [Address, UInt]
|
30
|
+
def airdrop( to:, amount: )
|
31
|
+
assert amount > 0, 'Amount must be positive'
|
32
|
+
assert amount <= @perMintLimit, 'Exceeded mint limit'
|
33
|
+
assert @totalSupply + amount <= @maxSupply, 'Exceeded max supply'
|
34
|
+
|
35
|
+
_mint( to: to, amount: amount )
|
36
|
+
end
|
37
|
+
end # class PublicMintERC20
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Rubysol
|
2
|
+
module Module
|
3
|
+
module Contracts
|
4
|
+
MAJOR = 0
|
5
|
+
MINOR = 1
|
6
|
+
PATCH = 0
|
7
|
+
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
8
|
+
|
9
|
+
def self.version
|
10
|
+
VERSION
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.banner
|
14
|
+
"rubysol-contracts/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.root
|
18
|
+
File.expand_path( File.dirname(File.dirname(File.dirname(File.dirname(__FILE__)))) )
|
19
|
+
end
|
20
|
+
|
21
|
+
end # module Contracts
|
22
|
+
end # module Module
|
23
|
+
end # module Rubysol
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'solidity/typed'
|
2
|
+
require 'rubysol'
|
3
|
+
|
4
|
+
## our own code / contracts
|
5
|
+
require_relative 'contracts/version'
|
6
|
+
require_relative 'contracts/erc20.rb'
|
7
|
+
require_relative 'contracts/erc20_liquidity_pool.rb'
|
8
|
+
require_relative 'contracts/erc721.rb'
|
9
|
+
require_relative 'contracts/ether_erc20_bridge.rb'
|
10
|
+
require_relative 'contracts/ethscription_erc20_bridge.rb'
|
11
|
+
require_relative 'contracts/generative_erc721.rb'
|
12
|
+
require_relative 'contracts/open_edition_erc721.rb'
|
13
|
+
require_relative 'contracts/public_mint_erc20.rb'
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
puts Rubysol::Module::Contracts.banner ## say hello
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubysol-contracts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gerald Bauer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubysol
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '7'
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '4.0'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '7'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: hoe
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '4.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '4.0'
|
61
|
+
description: rubysol-contracts - standard contracts (incl. erc20, erc721, etc) for
|
62
|
+
ruby for layer 1 (l1) with "off-chain" indexer
|
63
|
+
email: gerald.bauer@gmail.com
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files:
|
67
|
+
- CHANGELOG.md
|
68
|
+
- Manifest.txt
|
69
|
+
- README.md
|
70
|
+
files:
|
71
|
+
- CHANGELOG.md
|
72
|
+
- Manifest.txt
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- lib/rubysol/contracts.rb
|
76
|
+
- lib/rubysol/contracts/erc20.rb
|
77
|
+
- lib/rubysol/contracts/erc20_liquidity_pool.rb
|
78
|
+
- lib/rubysol/contracts/erc721.rb
|
79
|
+
- lib/rubysol/contracts/ether_erc20_bridge.rb
|
80
|
+
- lib/rubysol/contracts/ethscription_erc20_bridge.rb
|
81
|
+
- lib/rubysol/contracts/generative_erc721.rb
|
82
|
+
- lib/rubysol/contracts/open_edition_erc721.rb
|
83
|
+
- lib/rubysol/contracts/public_mint_erc20.rb
|
84
|
+
- lib/rubysol/contracts/version.rb
|
85
|
+
homepage: https://github.com/s6ruby/rubidity
|
86
|
+
licenses:
|
87
|
+
- Public Domain
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options:
|
91
|
+
- "--main"
|
92
|
+
- README.md
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '2.3'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubygems_version: 3.4.10
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: rubysol-contracts - standard contracts (incl. erc20, erc721, etc) for ruby
|
110
|
+
for layer 1 (l1) with "off-chain" indexer
|
111
|
+
test_files: []
|