Skip to content

Commit 0db4a4e

Browse files
Merge pull request #7 from everFinance/add-bundles
Implementation ANS104: bundle data
2 parents 8b24aca + 8bb5dd0 commit 0db4a4e

19 files changed

+805
-141
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
main.go
2+
go.sum
23
test-keyfile.json
34
.DS_Store

README.md

+153-97
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ go get github.com/everFinance/goar
88

99
### Example
1010

11-
Send winston
11+
#### Send AR or Winston
1212

1313
```golang
1414
package main
1515

1616
import (
1717
"fmt"
1818
"math/big"
19-
2019
"github.com/everFinance/goar/types"
2120
"github.com/everFinance/goar"
2221
)
@@ -27,54 +26,51 @@ func main() {
2726
panic(err)
2827
}
2928

30-
id, err := wallet.SendWinston(
31-
big.NewInt(1), // Winston amount
29+
id, err := wallet.SendAR(
30+
//id, err := wallet.SendWinston(
31+
big.NewFloat(1.0), // AR amount
3232
{{target}}, // target address
33-
[]types.Tag{
34-
types.Tag{
35-
Name: "testSendWinston",
36-
Value: "1",
37-
},
38-
},
33+
[]types.Tag{},
3934
)
4035

4136
fmt.Println(id, err) // {{id}}, nil
4237
}
4338

4439
```
4540

46-
Send Data
41+
#### Send Data
4742

4843
```golang
49-
package main
50-
51-
import (
52-
"fmt"
53-
54-
"github.com/everFinance/goar/types"
55-
"github.com/everFinance/goar"
44+
id, err := wallet.SendData(
45+
[]byte("123"), // Data bytes
46+
[]types.Tag{
47+
types.Tag{
48+
Name: "testSendData",
49+
Value: "123",
50+
},
51+
},
5652
)
5753

58-
func main() {
59-
wallet, err := goar.NewWalletFromPath("./test-keyfile.json", "https://arweave.net")
60-
if err != nil {
61-
panic(err)
62-
}
54+
fmt.Println(id, err) // {{id}}, nil
55+
```
6356

64-
id, err := wallet.SendData(
65-
[]byte("123"), // Data bytes
66-
[]types.Tag{
67-
types.Tag{
68-
Name: "testSendData",
69-
Value: "123",
70-
},
71-
},
72-
)
57+
#### Send Data SpeedUp
7358

74-
fmt.Println(id, err) // {{id}}, nil
75-
}
76-
```
59+
Arweave occasionally experiences congestion, and a low Reward can cause a transaction to fail; use speedUp to accelerate the transaction.
7760

61+
```golang
62+
speedUp := int64(50) // means reward = reward * 150%
63+
id, err := wallet.SendDataSpeedUp(
64+
[]byte("123"), // Data bytes
65+
[]types.Tag{
66+
types.Tag{
67+
Name: "testSendDataSpeedUp",
68+
Value: "123",
69+
},
70+
},speedUp)
71+
72+
fmt.Println(id, err) // {{id}}, nil
73+
```
7874
### Components
7975

8076
#### Client
@@ -93,6 +89,8 @@ func main() {
9389
- [x] GetLastTransactionID
9490
- [x] GetBlockByID
9591
- [x] GetBlockByHeight
92+
- [x] BatchSendItemToBundler
93+
- [x] GetBundle
9694

9795
Initialize the instance:
9896

@@ -113,6 +111,9 @@ arClient := goar.NewClient("https://arweave.net", proxyUrl)
113111
- [x] SendData
114112
- [x] SendDataSpeedUp
115113
- [x] SendTransaction
114+
- [x] CreateAndSignBundleItem
115+
- [x] SendBundleTxSpeedUp
116+
- [x] SendBundleTx
116117

117118
Initialize the instance, use a keyfile.json:
118119

@@ -144,6 +145,7 @@ Package for Arweave develop toolkit.
144145
- [x] SignTransaction
145146
- [x] GetSignatureData
146147
- [x] VerifyTransaction
148+
- [x] NewBundle
147149

148150
#### RSA Threshold Cryptography
149151

@@ -175,8 +177,8 @@ signedData01, err := ts.ThresholdSign(signer01)
175177

176178
// assemble sign
177179
signedShares := tcrsa.SigShareList{
178-
signedData01,
179-
...
180+
signedData01,
181+
...
180182
}
181183
signature, err := ts.AssembleSigShares(signedShares)
182184

@@ -203,66 +205,66 @@ The method of sumbitting a data transaction is to use chunk uploading. This meth
203205
Simple example:
204206

205207
```golang
206-
arNode := "https://arweave.net"
207-
w, err := goar.NewWalletFromPath("../example/testKey.json", arNode) // your wallet private key
208-
anchor, err := w.Client.GetTransactionAnchor()
209-
if err != nil {
210-
return
211-
}
212-
data, err := ioutil.ReadFile("./2.3MBPhoto.jpg")
213-
if err != nil {
214-
return
215-
}
216-
tx.LastTx = anchor
217-
reward, err := w.Client.GetTransactionPrice(data, nil)
218-
if err != nil {
219-
return
220-
}
208+
arNode := "https://arweave.net"
209+
w, err := goar.NewWalletFromPath("../example/testKey.json", arNode) // your wallet private key
210+
anchor, err := w.Client.GetTransactionAnchor()
211+
if err != nil {
212+
return
213+
}
214+
data, err := ioutil.ReadFile("./2.3MBPhoto.jpg")
215+
if err != nil {
216+
return
217+
}
218+
tx.LastTx = anchor
219+
reward, err := w.Client.GetTransactionPrice(data, nil)
220+
if err != nil {
221+
return
222+
}
221223

222-
tx := &types.Transaction{
223-
Format: 2,
224-
Target: "",
225-
Quantity: "0",
226-
Tags: utils.TagsEncode(tags),
227-
Data: utils.Base64Encode(data),
228-
DataSize: fmt.Sprintf("%d", len(data)),
229-
Reward: fmt.Sprintf("%d", reward*(100+speedFactor)/100),
230-
}
231-
if err = utils.SignTransaction(tx, w.PubKey, w.PrvKey); err != nil {
232-
return
233-
}
224+
tx := &types.Transaction{
225+
Format: 2,
226+
Target: "",
227+
Quantity: "0",
228+
Tags: utils.TagsEncode(tags),
229+
Data: utils.Base64Encode(data),
230+
DataSize: fmt.Sprintf("%d", len(data)),
231+
Reward: fmt.Sprintf("%d", reward*(100+speedFactor)/100),
232+
}
233+
if err = utils.SignTransaction(tx, w.PubKey, w.PrvKey); err != nil {
234+
return
235+
}
234236

235-
id = tx.ID
237+
id = tx.ID
236238

237-
uploader, err := goar.CreateUploader(w.Client, tx, nil)
238-
if err != nil {
239-
return
240-
}
241-
for !uploader.IsComplete() {
242-
err = uploader.UploadChunk()
243-
if err != nil {
244-
return
245-
}
246-
}
239+
uploader, err := goar.CreateUploader(w.Client, tx, nil)
240+
if err != nil {
241+
return
242+
}
243+
for !uploader.IsComplete() {
244+
err = uploader.UploadChunk()
245+
if err != nil {
246+
return
247+
}
248+
}
247249
```
248250

249251
##### Breakpoint continuingly
250252

251253
You can resume an upload from a saved uploader object, that you have persisted in storage some using json.marshal(uploader) at any stage of the upload.To resume, parse it back into an object and pass it to getUploader() along with the transactions data:
252254

253255
```golang
254-
uploaderBuf, err := ioutil.ReadFile("./jsonUploaderFile.json")
255-
lastUploader := &txType.TransactionUploader{}
256-
err = json.Unmarshal(uploaderBuf, lastUploader)
257-
assert.NoError(t, err)
258-
259-
// new uploader object by last time uploader
260-
newUploader, err := txType.CreateUploader(wallet.Client, lastUploader.FormatSerializedUploader(), bigData)
261-
assert.NoError(t, err)
262-
for !newUploader.IsComplete() {
263-
err := newUploader.UploadChunk()
264-
assert.NoError(t, err)
265-
}
256+
uploaderBuf, err := ioutil.ReadFile("./jsonUploaderFile.json")
257+
lastUploader := &txType.TransactionUploader{}
258+
err = json.Unmarshal(uploaderBuf, lastUploader)
259+
assert.NoError(t, err)
260+
261+
// new uploader object by last time uploader
262+
newUploader, err := txType.CreateUploader(wallet.Client, lastUploader.FormatSerializedUploader(), bigData)
263+
assert.NoError(t, err)
264+
for !newUploader.IsComplete() {
265+
err := newUploader.UploadChunk()
266+
assert.NoError(t, err)
267+
}
266268
```
267269

268270
When resuming the upload, you must provide the same data as the original upload. When you serialize the uploader object with json.marshal() to save it somewhere, it will not include the data.
@@ -272,17 +274,71 @@ When resuming the upload, you must provide the same data as the original upload.
272274
You can also resume an upload from just the transaction ID and data, once it has been mined into a block. This can be useful if you didn't save the uploader somewhere but the upload got interrupted. This will re-upload all of the data from the beginning, since we don't know which parts have been uploaded:
273275

274276
```golang
275-
bigData, err := ioutil.ReadFile(filePath)
276-
txId := "myTxId"
277-
278-
// get uploader by txId and post big data by chunks
279-
uploader, err := goar.CreateUploader(wallet.Client, txId, bigData)
280-
assert.NoError(t, err)
281-
for !uploader.IsComplete() {
282-
err := uploader.UploadChunk()
283-
assert.NoError(t, err)
284-
}
277+
bigData, err := ioutil.ReadFile(filePath)
278+
txId := "myTxId"
279+
280+
// get uploader by txId and post big data by chunks
281+
uploader, err := goar.CreateUploader(wallet.Client, txId, bigData)
282+
assert.NoError(t, err)
283+
for !uploader.IsComplete() {
284+
err := uploader.UploadChunk()
285+
assert.NoError(t, err)
286+
}
285287
```
286288

287289
##### NOTE: About all chunk transfer full example can be viewed in path `./example/chunks_tx_test.go`
290+
288291
---
292+
### About Arweave Bundles
293+
1. `goar` implemented creating,editing,reading and verifying bundles tx
294+
2. This is the [ANS-104](https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md) standard protocol and refers to the [arbundles](https://github.com/Bundler-Network/arbundles) js-lib implement
295+
3. more example can be viewed in path `./example/bundle_test.go`
296+
297+
#### CreateBundle
298+
```go
299+
w, err := goar.NewWalletFromPath(privateKey, arNode)
300+
if err != nil {
301+
panic(err)
302+
}
303+
304+
// Create Item
305+
data := []byte("upload update...")
306+
signatureType := 1 // currently only supply type 1
307+
target := "" // option
308+
anchor := "" // option
309+
tags := []types.Tags{}{} // bundle item tags
310+
item01, err := w.CreateAndSignBundleItem(data, 1, target, anchor, tags)
311+
// Same as create item
312+
item02
313+
item03
314+
....
315+
316+
items := []types.BundleItem{item01, item02, item03 ...}
317+
318+
bundle, err := utils.NewBundle(items...)
319+
320+
```
321+
322+
#### Send Item to Bundler
323+
It is not necessary, The purpose is to create an index for the Bundler gateway
324+
```go
325+
resp, err := w.Client.BatchSendItemToBundler(items)
326+
```
327+
328+
#### Send Bundle Tx
329+
```go
330+
txId, err := w.SendBundleTx(bd.BundleBinary, arTxtags)
331+
```
332+
333+
#### Get Bundle and Verify
334+
```go
335+
id := "lt24bnUGms5XLZeVamSPHePl4M2ClpLQyRxZI7weH1k"
336+
bundle, err := cli.GetBundle(id)
337+
338+
// verify
339+
for _, item := range bundle.Items {
340+
err = utils.VerifyBundleItem(item)
341+
assert.NoError(t, err)
342+
}
343+
```
344+
---

0 commit comments

Comments
 (0)