-
Angelo Capossele authored
*
Update double-spend tool * Fix linter warnings * Fix review commentsAngelo Capossele authored*
Update double-spend tool * Fix linter warnings * Fix review comments
double-spend.go 3.01 KiB
package main
import (
"fmt"
"net/http"
"sync"
"time"
"github.com/iotaledger/goshimmer/client"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet"
)
func main() {
clients := make([]*client.GoShimmerAPI, 2)
node1APIURL := "http://127.0.0.1:8080"
node2APIURL := "http://127.0.0.1:8090"
if node1APIURL == node2APIURL {
fmt.Println("Please use 2 different nodes to issue a double-spend")
return
}
clients[0] = client.NewGoShimmerAPI(node1APIURL, http.Client{Timeout: 60 * time.Second})
clients[1] = client.NewGoShimmerAPI(node2APIURL, http.Client{Timeout: 60 * time.Second})
myWallet := wallet.New()
myAddr := myWallet.Seed().Address(0)
if _, err := clients[0].SendFaucetRequest(myAddr.String()); err != nil {
fmt.Println(err)
return
}
var myOutputID string
var confirmed bool
// wait for the funds
for i := 0; i < 10; i++ {
time.Sleep(5 * time.Second)
resp, err := clients[0].GetUnspentOutputs([]string{myAddr.String()})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Waiting for funds to be confirmed...")
for _, v := range resp.UnspentOutputs {
if len(v.OutputIDs) > 0 {
myOutputID = v.OutputIDs[0].ID
confirmed = v.OutputIDs[0].InclusionState.Confirmed
break
}
}
if myOutputID != "" && confirmed {
break
}
}
if myOutputID == "" {
fmt.Println("Could not find OutputID")
return
}
if !confirmed {
fmt.Println("OutputID not confirmed")
return
}
out, err := transaction.OutputIDFromBase58(myOutputID)
if err != nil {
fmt.Println("malformed OutputID")
return
}
// issue transactions which spend the same output
conflictingTxs := make([]*transaction.Transaction, 2)
conflictingMsgIDs := make([]string, 2)
receiverSeeds := make([]*wallet.Seed, 2)
var wg sync.WaitGroup
for i := range conflictingTxs {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
// create a new receiver wallet for the given conflict
receiverSeeds[i] = wallet.NewSeed()
destAddr := receiverSeeds[i].Address(0)
tx := transaction.New(
transaction.NewInputs(out),
transaction.NewOutputs(map[address.Address][]*balance.Balance{
destAddr: {
{Value: 1337, Color: balance.ColorIOTA},
},
}))
tx = tx.Sign(signaturescheme.ED25519(*myWallet.Seed().KeyPair(0)))
conflictingTxs[i] = tx
valueObject := valuepayload.New(valuepayload.GenesisID, valuepayload.GenesisID, tx)
// issue the tx
conflictingMsgIDs[i], err = clients[i].SendPayload(valueObject.Bytes())
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("issued conflict transaction %s\n", conflictingMsgIDs[i])
}(i)
}
wg.Wait()
}