Coder Social home page Coder Social logo

iota.go's Introduction

iota.go

Official Go library.

This library allows you to do the following:

  • Create blocks with tagged data and transaction payloads
  • Get blocks and outputs
  • Sign transactions
  • Generate addresses
  • Interact with an IOTA node
  • Act as a foundation for Go based node software

If you need to have more sophisticated account management, have a look at wallet.rs for which we also provide bindings in Python and JavaScript.

Requirements

This library was mainly tested with Go version 1.16.x

To use the library, we recommend you update Go to the latest stable version.

Using the library

Using the library is easy, just go get it as any other dependency:

go get github.com/iotaledger/iota.go/v4

API reference

You can read the API reference here.

Joining the discussion

If you want to get involved in the community, need help with setting up, have any issues or just want to discuss IOTA with other people, feel free to join our Discord in the #clients-dev and #clients-discussion channels.

License

The MIT license can be found here.

iota.go's People

Contributors

abadojack avatar alexsporn avatar bernardoaraujor avatar cwarner818 avatar cyberphysic4l avatar daria305 avatar dependabot[bot] avatar dindinw avatar heinrichreimer avatar hmoog avatar iotmod avatar jakescahill avatar jeffwillette avatar jkrvivian avatar jkuruvilla avatar jonastheis avatar jorgemmsilva avatar karimodm avatar knarz avatar luca-moser avatar lzpap avatar maeck70 avatar muxxer avatar oliviasaa avatar philippgackstatter avatar piotrm50 avatar pomyk avatar siziyman avatar veorq avatar wollac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iota.go's Issues

Add ExtractJSON()

Add ExtractJSON(txs transaction.Transactions, obj interfrace{}) which takes a slice of transactions and an object interface in which to unmarshal the value into from the given transactions.

Should support the following formats:

  • "{ \"message\": \"hello\" }"
  • "[1, 2, 3]"
  • "true", "false" and "null"
  • "hello"
  • 123

Installing Giota on ARM64 fails

When installing the giota library on a system that runs the ARM64v8 architecture, the curl_transform function fails to compile. I suspect this has something to do with the fact that int8 is not signed on the ARM64 architecture.

go get -u github.com/iotaledger/giota
# github.com/iotaledger/giota
go/src/github.com/iotaledger/giota/pow_c.go: In function ‘para’:
go/src/github.com/iotaledger/giota/pow_c.go:193:5: warning: case label value is less than minimum value for type
     case -1:
     ^
# github.com/iotaledger/giota
go/src/github.com/iotaledger/giota/curl_transform.go:72: cannot convert &state[0] (type *int8) to type *C.char

De10 nano fpga support request.

Description

Is there any way to add the de10 nano fpga go code added to this? It can be found on LampaLab's github here.

https://github.com/LampaLab/giota/blob/master/pow_fpga.go

Thanks it would come in handy if it was able to be added. =)

Motivation

There are some that are using the fpga as pow

Requirements

Just add it to an available pow possibility

Open Questions (optional)

Anything you want to discuss.

Am I planning to do it myself with a PR?

No

Comments are inconsistent

I have noticed some grammatical errors in the comments as well as inconsistent spaces after the //'s, and missing comments on exported functions/methods. I would like to go through and fix these and familiarize myself with the code in the process but I just wanted to ask first to make sure the changes are welcome and the project will still be actively developed in the near future

Implement tests for all packages

Currently all tests are very mixed and don't follow a steady pattern. http://onsi.github.io/ginkgo/ will be used to implement BDD style tests. API functions interacting with IRI nodes will be mocked.

Implement tests in packages:

  • address
  • api
  • bundle
  • checksum
  • converter
  • curl
  • guards
  • kerl
  • pow
  • signing
  • transaction
  • trinary
  • units

Contributing question regarding PR without any API changes

Technically this is neither feature request nor bug, but I hope it's okay to post such questions here, since it's directly connected to code contribution process.

Should PR without API changes include additional tests and/or examples? I will provide motivation and explanation, of course.
I have read the guide in readme, it seems like the case in question isn't covered.
I can provide test to prove that implementation change will be functionally equivalent to one already present in the repository, but it seems like such a test has no place in repository itself and probably should only exist as supplementary material for pull request (gist/link in description).

Thanks in advance!

Dependency cannot be resolved

I am using dep ensure to add giota as a dependency. I recently ran into this error:

Solving failure: No versions of github.com/iotaledger/giota met constraints:
	master: unable to deduce repository and source type for "leb.io/hashland": unable to read metadata: unable to fetch raw metadata: failed HTTP request to URL "http://leb.io/hashland?go-get=1": Get http://leb.io/hashland?go-get=1: dial tcp 104.131.190.18:80: getsockopt: connection refused

Can't create transaction

I'm a japanses, if I miss issue sentenses, Sorry.

iri 1.7.1
iota.go latest(2019/07/29)

I attempted to create a transaction.
When I run example program, the following error messages are displayed:

panic: error message: This operation cannot be executed: The subtangle has not been updated yet.;http status code: 400;

when run example program displayed following error messages :
07/29 21:46:52.159 [XNIO-1 task-14] INFO API:582 - Tip selection failed: This operation cannot be executed: The subtangle has not been updated yet.

example program:

package main

import (
	"fmt"

	"github.com/iotaledger/iota.go/address"
	. "github.com/iotaledger/iota.go/api"
	"github.com/iotaledger/iota.go/bundle"
	. "github.com/iotaledger/iota.go/consts"
	"github.com/iotaledger/iota.go/pow"
	"github.com/iotaledger/iota.go/trinary"
)

var endpoint = "http://localhost:14265"

// must be 81 trytes long and truly random
var seed = trinary.Trytes("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")

// difficulty of the proof of work required to attach a transaction on the tangle
const mwm = 14

// how many milestones back to start the random walk from
const depth = 3

// must be 90 trytes long (with checksum)
const recipientAddress = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"

func main() {

	// get the best available PoW implementation
	_, proofOfWorkFunc := pow.GetFastestProofOfWorkImpl()

	// create a new API instance
	api, err := ComposeAPI(HTTPClientSettings{
		URI: endpoint,
		// (!) if no PoWFunc is supplied, then the connected node is requested to do PoW for us
		// via the AttachToTangle() API call.
		LocalProofOfWorkFunc: proofOfWorkFunc,
	})
	must(err)

	// create a transfer to the given recipient address
	// optionally define a message and tag
	transfers := bundle.Transfers{
		{
			// must be 90 trytes long (include the checksum)
			Address: recipientAddress,
			Value:   80,
		},
	}

	// create inputs for the transfer
	inputs := []Input{
		{
			// must be 90 trytes long (include the checksum)
			Address:  "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
			Security: SecurityLevelMedium,
			KeyIndex: 0,
			Balance:  100,
		},
	}

	// create an address for the remainder.
	// in this case we will have 20 iotas as the remainder, since we spend 100 from our input
	// address and only send 80 to the recipient.
	remainderAddress, err := address.GenerateAddress(seed, 1, SecurityLevelMedium, true)
	must(err)

	// we don't need to set the security level or timestamp in the options because we supply
	// the input and remainder addresses.
	prepTransferOpts := PrepareTransfersOptions{Inputs: inputs, RemainderAddress: &remainderAddress}

	// prepare the transfer by creating a bundle with the given transfers and inputs.
	// the result are trytes ready for PoW.
	trytes, err := api.PrepareTransfers(seed, transfers, prepTransferOpts)
	must(err)

	// you can decrease your chance of sending to a spent address by checking the address before
	// broadcasting your bundle.
	spent, err := api.WereAddressesSpentFrom(transfers[0].Address)
	must(err)

	if spent[0] {
		fmt.Println("recipient address is spent from, aborting transfer")
		return
	}

	// at this point the bundle trytes are signed.
	// now we need to:
	// 1. select two tips
	// 2. do proof-of-work
	// 3. broadcast the bundle
	// 4. store the bundle
	// SendTrytes() conveniently does the steps above for us.
	bndl, err := api.SendTrytes(trytes, depth, mwm)
	must(err)

	fmt.Println("broadcasted bundle with tail tx hash: ", bundle.TailTransactionHash(bndl))
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

My transaction seems that doesn't approve past transaction. Because of no transactions on past.

investigate if Go produces different bundles from the Java lib

According to the exchange between cfb and the MIT Researchers there might be an issue with bundles created by this library, as the foundation was not able to validate bundles generated by the MIT people who apparently used this library.

[...]
We can’t get your bundles to be validated successfully. It’s unclear if it’s a bug in the unfinished Go version or something else, we can’t check it right now because of the preparations to the snapshot.
[...]

Additional examples

Hi!

It would be awesome to have some examples that show the following:

  • Generate a new address and attach the address to the tangle
  • Move balance from previously used and therefore insecure address to a newly generated address
  • Send amount to recipient and move leftover balance to newly generated address
  • Send to multiple recipients
  • Promote a transaction

This would really help a lot.

Best regards
Tobias

Suggestion: Add possibility to explicitely specify input addresses in PrepareTransfers.

Currently PrepareTransfers require inputs []AddressInfo with seed and address indices. It is redundant to generate addresses if they are already known in the context and can be provided as parameters. Also it is not always convenient to provide address index and security level.
Would be convenient to have options just give slice with input addresses.
Similarly Python library does with ProposedTransactions

Feature request: No track of all addresses

Description

Badger store should keep a track of all addresses Hashes and there should be a method in account to retrieve them instead of using store.GetDepositAddresses(account.ID())

Motivation

api.GetAccountData is deprecated.

Am I planning to do it myself with a PR?

Yes

MAM handling layer

Description

A layer above MAMCreate and MAMParse to easily transmit and receive MAM messages.

Motivation

To pass messages through the tangle.

Am I planning to do it myself with a PR?

Yes

MinTrits and TrailingZeros should return int

Bug description

The functions MinTrits and TrailingZeros in the trinary package return a number of elements and thus should return int.
In Go the count or number of elements usually has the platform dependent type int (see, e.g. len,
copy, Reader.Read, etc.). Both functions refer to a number of trits, i.e. number of int8 in a slice. As such, results larger than int are technical and mathematical not possible on any architecture.
On the other hand, having the fixed type of int64 will lead to many unnecessary conversions and could result in expensive 64-bit computations on 32-bit hardware.

Suggested behavior

Change the signature of MinTrits and TrailingZeros to return int.
However, unfortunately this technically means a breaking change as user code using those functions needs to be adapted and I am unsure what the correct course of action is for API changes.

NewSeed can fail to generate valid seed

Generating a valid seed can fail whenever the bytes returned are too small to generate a hex string of 81 characters.

func NewSeed() Trytes {
	b := make([]byte, 48)
	if _, err := rand.Read(b); err != nil {
		panic(err)
	}
	txt := new(big.Int).SetBytes(b).Text(27)
	t := make([]rune, 81)
	for i, c := range txt {

txt here can be < 81 characters long, which means that we end up with the last rune of t being \x00.

How to reproduce:
run for i in {0..100}; do go test -v -race -run TestAddress .; done; and you're guaranteed to get a couple of invalid seeds.

can not transfer success

I build a simple transfer like transfer_test.go but i can not success.

The example put 5 transaction into the bundle but it has only one output like this "https://thetangle.org/bundle/YXCQVBAUX9ISLJPQWEFGHCKKZFBHAPCFAFHOIVVWVAGFFHJPSNSVHFOAKNUYDC9BSSLGPRAHTLKHUVVXZ".

I get nothing when I findTransaction by bundle. its ok when i use java-lib or js-lib with the same node.

this is my code, please help me. i change many seed which have iota but i can not success.

package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/iotaledger/giota"
)

func main() {
	trytesFrom := "BBHCNPZOZNIFOXQZ9AAAAAAA99XUVPMYQEYERUVWBZXUBWWBPTJXVYUSHWFNJROGZPZUUJQQXAYGDI99A"
	seed, err := giota.ToTrytes(trytesFrom)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}

	//api
	httpClient := &http.Client{
		Timeout: 600 * time.Second,
	}
	//api := giota.NewAPI("http://ioTaUser:[email protected]:14625", httpClient)
	api := giota.NewAPI("http://47.89.54.66:14600", httpClient)

	//send transaction
	trs := []giota.Transfer{
		giota.Transfer{
			Address: "LWADKFFFRNLGLQVILXUTIZIZVNNAJRWOIAHGLDAGGEFTIUGKBYSHPQDNMAIAFJZ9XQUSCEKGZYEQ9CTLC",
			Value:   10,
			Tag:     "TAGTEST",
			Message: "MSGTEST",
		},
	}
	bundle, err := giota.Send(api, seed, 3, trs, 14, nil)
	if err != nil {
		fmt.Printf("send err: %v\n", err)
		return
	}

	//print bundle result
	fmt.Printf("bundle: %s\n", bundle.Hash())
	for _, tx := range bundle {
		PrintTx(&tx)
	}
	fmt.Printf("send success")
}

func PrintTx(tx *giota.Transaction) {
	fmt.Printf("\nHash: %s\n", tx.Hash())
	fmt.Printf("SignatureMessageFragment: %s\n", tx.SignatureMessageFragment)
	fmt.Printf("Address: %s\n", tx.Address)
	fmt.Printf("Value: %d\n", tx.Value)
	fmt.Printf("Timestamp: %v\n", tx.Timestamp)
	fmt.Printf("CurrentIndex: %d\n", tx.CurrentIndex)
	fmt.Printf("LastIndex: %d\n", tx.LastIndex)
	fmt.Printf("Bundle: %s\n", tx.Bundle)
	fmt.Printf("TrunkTransaction: %s\n", tx.TrunkTransaction)
	fmt.Printf("BranchTransaction: %s\n", tx.BranchTransaction)
	fmt.Printf("Tag: %s\n", tx.Tag)
	fmt.Printf(":AttachmentTimestamp %s\n", tx.AttachmentTimestamp)
	fmt.Printf(":AttachmentTimestampLowerBound  %s\n", tx.AttachmentTimestampLowerBound)
	fmt.Printf(":AttachmentTimestampUpperBound %s\n", tx.AttachmentTimestampUpperBound)
	fmt.Printf(":Nonce: %s\n", tx.Nonce)
}

The project name `.go` confuses the compiler a lot

I recently discovered that if one forks this repo and adds a new package that uses some of the IOTA library internals - the compilation/tests are failing.

Some investigation / help from #go-nuts@freenode channel revealed that the suffix .go in the package name confuses the go tool in certain cases.

if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
...

As a test, I renamed my local copy into iota.lib.golang - and the problem vanished.

Not sure whether it's a good idea to rename this package and what how many packages depend on this one, but just to keep this problem in mind.

Switch to Googles Sha3

I've seen that the lib imports an external Sha3 implementation from leb.io/hashland/keccakpg. There is already a Sha3 implementation from Google in golang.org/x/crypto/sha3

The Google one has assembler optimized code for amd64. Is there a reason to use the 3rd party lib instead of the Google one?

Just curios.

Generate reference docs according to a layout

Description

We'd like to generate the reference documentation in this repo on every release.

Motivation

Have the documentation generated automatically.
Allow the documentation portal to pick up the new versions of the documentation on every release from this repo.
Have reference docs in a layout that is consistent across the ecosystem.

Requirements

  • Documentation is generated in a *specified folder on every new release.
  • Documentation adheres to specific layout. Each method has its own .MD file generated.

Description

We'd like to generate the reference documentation in this repo on every release.

Motivation

Have the documentation generated automatically.
Allow the documentation portal to pick up the new versions of the documentation on every release from this repo.
Have reference docs in a layout that is consistent across the ecosystem.

Requirements

  • Documentation is generated in a *specified folder on every new release.
  • Documentation adheres to specific layout. Each method has its own .MD file generated.

Note: We only have to keep the latest generated version. All previous versions will be persisted in the iotaledger/documentation repo.

*Folder structure

The docs should be generated in the following folders in this repo:
/docs/<project_name>/reference//<api_file>.MD

Later on, examples will be placed in:
/docs/<project_name>/examples/<api_file>.MD

pow_avx_test "FAILED"

Do you have plan to fix AVX implementation recently?

--- FAIL: TestPowAVX (1.41s)
        pow_avx_test.go:47: pow is illegal J9QTUNNMONCMIR9JBNMRC9SC9QTBRKBUVCBYBUITBHEICYVQ9HXEXSPWPU9KACTSDRSQBDOJPOOEAFVMP
        pow_avx_test.go:54: 20887 kH/sec on AVX PoW
--- FAIL: TestPowAVX1 (0.81s)
        pow_avx_test.go:47: pow is illegal J9QTUNNMONCMIR9JBNMRC9SC9QTBRKBUVCBYBUITBHEICYVQ9HXEXSPWPU9KACTSDRSQBDOJPOOEAFVMP
        pow_avx_test.go:61: 4812 kH/sec on AVX PoW
--- FAIL: TestPowAVX32 (0.23s)
        pow_avx_test.go:47: pow is illegal VGGPVYXYPVIVXGTOILZKRHPIPNDZZKSMRPUANDAHIOQMPOMFGJWKXVJV9TNPHGWBXZE9DQIOYZJMUHNZR
        pow_avx_test.go:69: 21435 kH/sec on AVX PoW
--- FAIL: TestPowAVX64 (0.45s)
        pow_avx_test.go:47: pow is illegal VGGPVYXYPVIVXGTOILZKRHPIPNDZZKSMRPUANDAHIOQMPOMFGJWKXVJV9TNPHGWBXZE9DQIOYZJMUHNZR
        pow_avx_test.go:77: 21554 kH/sec on AVX PoW

NewAddress generates wrong address compared to iota.lib.js

Hi,

Either I am doing something wrong or the libray is generating wrong addresses when calling giota.NewAddress(seed_trytes, 0, 2). Below is the output when comparing it with the iota.lib.js based electron light wallet.

trytesFrom:="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
trytes2,err:=giota.ToTrytes(trytesFrom)
adr,err:=giota.NewAddress(trytes2, 0, 2) //without checksum.

//ADDR:  SCRFLYEFBSRTSGYGWQNRUNVBXHDTIWJVGTHOFRTDLYNOQMHMJPVPNQCNQDFSVXNPYCLDCEJEWJVCFBVKS
iota.api.getNewAddress('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', {index: 0, total: 1, security:2}, function (error, addy) { if(error) { console.log(error); } else { console.log(addy); }});
//ADDR:  XUERGHWTYRTFUYKFKXURKHMFEVLOIFTTCNTXOGLDPCZ9CJLKHROOPGNAQYFJEPGK9OKUQROUECBAVNXRX

The address generated by the light wallet looks good (as it has a transaction history)

Please make sure people are not losing funds because of this by adding some unittests to check for address gen inconsistencies.

Feature request: Syncing (importing) of existing seeds

Description

Account Module (shortly AM) is a great addition to the IOTA stack, but for further adoption I think there's a crucial feature missing. That is, the creation of "new" Accounts with existing/old/previously used seeds.

Motivation

With the usage of the AM being recommended due to its statefullness over the manual implementation of seed management and standard lib usage, it is crucial to cover both freshly created seeds and already used seeds. One AM per device is understandable as it would be impossible to synchronize the same AM over multiple devices, but a feature of importing already old seeds and creating a new Account on a single device should be doable, no? For example now and in near future, most companies, developers and people integrating IOTA into their system rely on standard libs to do the work fast and well, while all using own implementations of seed management, which could be not-safe or inefficient. By having a way of an easy transition from own implementation to a well vetted, optimized and open source official implementation of the AM offered by IF could have great impact on their processes and ease of use of the Tangle. That being said, I think there could be a way to implement a procedure/syncing method, that takes in an old seed, and starts syncing (much like Trinity by checking n amount of addresses (or something similar)) and build up a local state of the Account, much like it is now. This could perhaps be even extended so the currently existing Accounts have a method of syncing. This could also allow the same Account to be on multiple devices as long as they never run simultaneously, but take turns running and sync their state beforehand.

Requirements

  • Syncing method that takes in an old seed, generates an "new" local Account, syncs up and builds its state (much like Trinity)
  • OPTIONAL (Syncing up/refreshing the state of any Account)

Open Questions (optional)

  • What would be the methods of syncing?
  • If it were to check n addresses like Trinity, how would the user interact with the lib in case there hasn't been enough addresses checked in the first iteration?

Am I planning to do it myself with a PR?

No.

Inconsistent input validation in trinary package

Bug description

The way arguments are validated in the trinary package is not consistent at all:

  • TritsToTrytes checks that the length is a multiple of 3, but not whether the int8 actually represent valid trits. However, there is a test that suggests that the input values are also validated.
  • TrytesToTrits checks that the input string indeed only contains valid tryte characters. There are tests for this behavior.
  • TritsToBytes performs no checks on the trits, even an empty Trits slice is valid.
  • BytesToTrits performs no checks that the bytes actually represent packed trits.
  • Pad and PadTrits don't perform any checks.
  • All other functions in trinary call one of those above and thus also have very inconsistent behavior.

Suggested behavior

For consistency, I would suggest to remove any non-trivial (i.e. length) checks from all the conversion functions but offer dedicated check functions for trits, trytes and bytes in case the user needs to validate.

Reasoning:

  • Most of the time these functions convert data that is the result of another library call and not user input, and as such known to be correct.
  • These functions are performance critical and input validation often takes the same time as the actual conversion.
  • For "random" input all of the conversion functions will panic even with out dedicated checks as the LUT are out-of-bounds.

Am I planning to do it myself with a PR?

I can absolutely do an PR for this, if the suggested changes are acceptable.

runtime errors after cross-compilation (Yocto/OpenEmbedded)

Since this issue is a bit outside of the context of plain golang development, writing the steps to reproduce the issue would be too lengthy and outside the scope of the project. So I apologize in advance for writing this issue while ignoring the template. I'll do my best to provide a really detailed description of the problem.

The Yocto Project is a Linux Foundation collaborative open source project whose goal is to produce tools and processes that enable the creation of Linux distributions for embedded and IoT software that are independent of the underlying architecture of the embedded hardware. OpenEmbedded is a build automation framework and cross-compile environment used to create Linux distributions for embedded devices. There's been Golang support on Yocto/OpenEmbedded for a while.

I'm writing a BitBake recipe for iota.go, which can be found at https://github.com/bernardoaraujor/meta-iota/blob/go-dev/recipes-iota/iota.go/iota.go_1.0.0.bb
The goal is to allow golang applications to make use of the IOTA Go API library on cross-compiled Embedded Linux distributions.

In the recipe, all dependencies from go.mod are covered (SRC_URI and SRCREV_*), and the cross-compiled go runtime is 1.12.
Unfortunately I can't find out how to run the ginkgo tests in this cross-compilation scenario, so I'm skipping unit tests by removing api/integration before it compiles.

Instead of unit testing, I'm using go-iota-workshop to make sure the cross-compiled APIs are functional.
Its go.mod sets iota.go to release 6, so that's the release I'm pointing at the BETA_V variable on iota.go_1.0.0.bb

When running on my Ubuntu machine (without cross compilation), all examples from go-iota-workshop work fine.
On the cross compiled target, helloworld, check_balance and zmq work fine. However, all other applications show runtime errors.

Here's a list of the error messages that I get when executing each example application. I executed each application several repeated times. Note that some of the messages vary on each iteration that the application is executed.

Although not every single time, one common pattern on the error messages is the fact that verification of trytes with regexp is usually the point where the execution breaks.
This usually happens when regexp is called by trinary.ValidTrytes() or guards.IsEmptyTrytes().

However there are also different cases, such as:

  • panic: invalid trytes (iota_go_send_tx, iota_go_send_value)
  • out of memory (iota_go_send_tx)
  • invalid memory address or nil pointer dereference (iota_go_receive_tx, iota_go_receive_data)
  • index out of range (iota_go_send_tx, iota_go_create_address, iota_go_send_value)
  • panic: at index 0 (iota_go_send_tx )
  • pure garbage (iota_go_send_tx )

The regexp errors are probably the most informative messages. There seems to be something wrong with the trit or tryte representation, although my inspection of the code (trinary/trinary.go) didn't show any exotic types related to them (only []int8 and string).

This could be CPU-architecture related, because I've tested on QEMUulated machines of x86-64 and arm64, and the behaviour is identical in both. They don't happen with 32 bits architectures, such as mips32.

My instincts tell me there's probably some compilation flag missing in the cross-compilation process (which is orchestrated by BitBake), leading to these runtime errors. Maybe BitBake is missing some go flag that leaves the executable objects missing some functionality.

I am avoiding the CGO-based PoW for the moment, so I don't think it's anything related to it either.

The fact that three example apps work (helloworld, check_balance and zmq) indicate that the library is at least partially working.

I'm really struggling to nail down the root cause of this issue. I would deeply appreciate any insights on this, although I know Yocto and OE might be somewhat exotic for most.

Feature request: improve ValidTrytes implementation to work faster, get rid of regexp

Description

Currently trinary.ValidTrytes func uses regular expression to validate string against a very simple pattern. Sadly, regular expressions in Golang standard library are quite slow (as will be proven further). It can be improved to work much faster, if the same check logic is implemented using for loop.

Motivation

First of all, ValidTrytes is a relatively "hot" function - it's called in different places of SDK, and it'll be executed quite a lot. Client apps might be running it even more often, if there's more validation in business logic itself. And since IOTA is aimed to work closely with internet of things, and Golang is often used as a language to develop for smaller devices, it's quite useful to have that function implemented as efficient as possible, if it doesn't increase cognitive load and cost of support too much. In my opinion, it does not do that, so it's "safe" improvement.

Requirements

  • Rewrite ValidTrytes function getting rid of regular expression
  • Provide benchmarks to verify performance improvement

Am I planning to do it myself with a PR?

Yes.
PR is ready (code, example benchmarks), I'll finish writing it up and submit it right after the issue creation.

Login flow & balances example?

I'm trying to read the balance of my wallet:

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/iotaledger/giota"
)

const Host = "http://node04.iotatoken.nl:14265"

func main() {
	client := http.Client{
		Timeout: 10 * time.Second,
	}
	println("Connecting")
	api := giota.NewAPI(Host, &client)
	seed, err := giota.ToTrytes("very secret seed here")
	if err != nil {
		log.Fatal(err)
	}
	println("Getting balances")
	inputs, err := giota.GetInputs(api, seed, 0, 400, 0, 12)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(inputs)
}

This one returns empty slice. Out of sniffing the protocol of the ledger app - it looks like it is trying to fetch all the addressess/bundles associated with the seed and then uses the single call to the getBalances command passing on all the addresses.

Can you please provide some example of how to do this with the Go client library?

TestDigests failing

9dc60c9 causes TestDigests to fail

EDIT: upon looking into the test, it seems that the input in that test must be stale from the Curl-P-81 update as well, but I am not sure how to verify the correctness of the digest that is output in the error message

=== RUN   TestDigests
--- FAIL: TestDigests (0.04s)
	sign_test.go:58: Digests() trits mismatch

		giota.Trits{-1, 1, -1, -1, 1, 0, 1, 0, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 1, -1, -1, 0, 1, -1, -1, 1, 1, 0, 1, 0, -1, 1, -1, -1, 1, -1, 0, -1, 0, 0, -1, 1, -1, 0, 0, 1, 1, -1, 1, 1, 0, 1, 1, -1, -1, 1, 1, 0, 0, 1, -1, 1, -1, 0, 0, -1, 0, 0, -1, 0, 1, 1, -1, 0, 1, 0, 0, 1, -1, 1, 1, 1, -1, 1, 0, -1, 1, -1, -1, 1, 1, 1, 0, 0, 0, -1, 1, -1, 0, 0, 1, 0, 0, 1, -1, 1, 1, 1, 0, 1, 1, -1, 1, 1, 0, 1, -1, 1, 0, -1, -1, 0, 0, -1, 0, 1, 1, 1, 1, -1, 1, 1, 0, 0, 1, -1, 1, 1, 0, -1, -1, 0, -1, 1, 0, 1, 1, 1, 1, 0, 1, -1, 1, -1, 1, -1, 0, 0, 0, 1, -1, 1, 0, 0, -1, 0, -1, 0, -1, 1, 1, 0, 1, -1, 1, -1, 0, 0, -1, -1, -1, -1, 1, -1, 0, 1, 1, 1, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 0, -1, -1, 1, -1, 0, 1, -1, 1, 1, 0, -1, 1, 1, 1, 0, 1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, 1, -1, -1, 1, 1, 1, -1, 0, -1, 1, 1, 1, 0, 1, -1, 1, 1, -1, 0, -1, -1, 0, -1, 1, -1, 0, 1, 0, -1, 1, 0, 1, 1, -1, -1, 0, -1, 1, 0, 1, 0, 0, -1, -1, -1, 0, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 0, -1, 0, 1, -1, 1, -1, 0, 0, 0, -1, 0, 1, 1, 0, 0, 1, 0, 0, 1, -1, 1, 1, 1, -1, -1, 0, -1, -1, 0, -1, 0, 1, 1, 0, -1, 0, 0, 0, 1, 1, 1, 1, -1, 1, 0, 0, 0, 0, 0, -1, 1, 1, -1, -1, 1, 0, 0, -1, -1, -1, 0, -1, 1, 0, 1, -1, 1, -1, 0, -1, -1, -1, -1, -1, 1, 0, 1, -1, 1, 0, -1, 1, 1, 1, -1, -1, 0, 1, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, 0, 1, 0, 0, -1, 1, 1, 0, 0, -1, 1, 0, 1, -1, 0, -1, 0, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 0, -1, -1, 1, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 0, -1, 0, -1, 1, -1, 0, -1, -1, 0, 0, 1, -1, -1, 1, 0, -1, 0, -1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, -1, 0, -1, 0}
		giota.Trits{0, -1, -1, 0, -1, -1, 0, 1, -1, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 1, 1, 1, -1, 0, 1, 0, 0, 1, 0, -1, 1, 0, 1, -1, 0, -1, -1, 0, 1, -1, 1, -1, -1, 0, 0, -1, 1, 0, -1, 0, -1, -1, -1, -1, 1, -1, 0, 0, 0, -1, 1, 1, 0, 0, 1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0, -1, 1, -1, -1, 1, 0, 1, 0, -1, 1, -1, 1, -1, 0, -1, -1, 1, -1, 0, 1, 1, 0, 0, 1, 1, -1, -1, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 0, 0, 1, 1, 1, 1, 1, 0, 0, -1, 1, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, -1, 1, -1, -1, 0, 1, 1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0, 1, 0, 0, -1, -1, -1, -1, -1, -1, 1, 0, 1, -1, 0, 1, 1, 1, 0, 1, 0, -1, -1, 1, -1, 1, 1, 0, -1, -1, 0, 0, 1, -1, -1, -1, 1, -1, 0, 0, 1, 0, -1, 0, 0, 1, 1, -1, -1, -1, 1, -1, 0, 1, 1, 0, 1, 0, 0, -1, 1, -1, 1, 1, 0, 0, 0, 1, -1, -1, 1, 0, 1, -1, -1, 0, -1, -1, -1, 1, 0, -1, 0, 1, -1, -1, 0, -1, 0, 1, 1, 0, 1, 0, -1, 1, -1, -1, 0, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 0, 1, 1, 0, 1, 0, -1, 1, -1, -1, -1, 1, 0, 0, -1, 0, 1, -1, 0, 0, 0, 0, -1, 1, 0, -1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, -1, 1, 1, -1, 0, 1, 0, 1, 0, 1, 1, 1, -1, -1, 0, 1, 1, 0, -1, -1, 0, -1, 0, 1, -1, -1, -1, 0, 1, 0, 0, 1, 1, -1, 0, -1, 1, 0, 0, -1, -1, -1, -1, 0, 1, 1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, -1, 0, 1, -1, -1, -1, -1, -1, 1, 0, 1, 0, 1, 0, -1, 1, -1, -1, -1, -1, 1, 1, -1, 0, 0, 0, 0, -1, 0, 1, 0, -1, 0, 1, 1, 1, 1, -1, -1, -1, 0, -1, 0, 0, -1, 1, 1, -1, -1, 1, 0, 1, 0, -1, 1, 0, -1, 1, -1, 0, -1, 1, 1, 1, -1, 1, -1, -1, 0, -1, 1, -1, 0, 0, -1, -1, 1, 1, -1, -1, -1, 1, -1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, -1, 0, 1, 0, -1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, -1, 1, 1, 0, 1, 1, -1, 1, 0, -1, -1, -1, 1, 0}

Address generation doesn't depend on the seed

package tests

import (
	"testing"

	"github.com/iotaledger/giota"
	"github.com/stretchr/testify/assert"
)

func TestAddressGen(t *testing.T) {
	seed1, err := giota.ToTrytes("SEEDTEST")
	assert.Nil(t, err)
	seed2, err := giota.ToTrytes("TESTSEED")
	assert.Nil(t, err)
	addr1, err := giota.NewAddress(seed1, 1, 2)
	assert.Nil(t, err)
	addr2, err := giota.NewAddress(seed2, 1, 2)
	assert.Nil(t, err)
	assert.NotEqual(t, addr1, addr2)
}

This test fails because of the same address value generated for the different seeds. Am I missing something here?

Neighbor struct does not include all info returned in getNeighbors curl call.

Struct and getNeighbors call must be expanded to match the current version of the curl equivalent.

// Neighbor is a part of response of GetNeighbors API.
type Neighbor struct {
	Address                     Address `json:"address"`
	NumberOfAllTransactions     int64   `json:"numberOfAllTransactions"`
	NumberOfInvalidTransactions int64   `json:"numberOfInvalidTransactions"`
	NumberOfNewTransactions     int64   `json:"numberOfNewTransactions"`
}

Current CURL response (IRI 1.4.2.1):

curl http://localhost:14265   -X POST   -H 'Content-Type: application/json'   -H 'X-IOTA-API-Version: 1'   -d '{"command": "getNeighbors"}'
{
    "duration": 0,
    "neighbors": [
        {
            "address": "xx.xx.xx.xx:14600",
            "connectionType": "tcp",
            "numberOfAllTransactions": 108804,
            "numberOfInvalidTransactions": 0,
            "numberOfNewTransactions": 9007,
            "numberOfRandomTransactionRequests": 1844,
            "numberOfSentTransactions": 88851
        },

Most likely other API calls are outdated as well. Need to asses.

promote method

I have used the sample code from the main page with Promote but it doesnt compile.. Are there any sample that will be available to showcase the situations.

tests hang sometimes

I am seeing tests hanging sometimes in different spots, for instance right now my tests are stuck at TestAPIGetTransactionsToApprove.

I can see this has something to do with attaching to the tangle, or a maybe the node it is trying to attach to...I haven't seen enough faults to be able to narrow down exactly where it is failing. @knarz do you know specifically what is causing this?

the tx hash is not correct

the tx hash for trytes

QQ9VLGQTJICJH9UZNSBXRSKBWVXCTRNGLJPEYFSZBISDCGBHGAV9TEHIMJS9LMQNHFNWVAXALKGESPWZMUMZPQCKCUFSEJZVHWZHZOEZBPTERXPHUQLQLZMENKOKAWMJ9LCFSIBSBEYCJQVQQMTMRJMDEKRXLCIRZFWQBRJYLPSK9XLWFYFTU9FBJATWPQRJBHWYJRUEXSXMBJLVWNYRTZJTHLEKDTWCGJ9OXDEZNWTKLTXXTKVFXDMRJUDAMDACRHJKZIJFJBZRVDLSTIMOWPTLLIVHCFUBMSQIPVPCSQAPZGHHNNQLWEHDTIQZQTAXJMTTROYOTIZSZKKQFXBHXFKSNAGZWHWEGXCKHSJQGBJGC9IKUSSJEAOHTPGPMIYPEXJXJKRLX9IOCUDKK9ONEUONYVGHRHXSAUZJXGVQNWSDZIYXXZMMJKRTOXSWJHBIMXPEMJTKIBSQKPICTKAQLJVOLZSGNVVBIOFJJKKJ9UBYKJWCBRPQLGBNEKEFRYCHB9PORAKEKTJZYZBFGZLONUJCPNINGUTYWTMDKTEPDASCHNVHXTUIOZ9PDALXKQYLILMUJEJWTYYAGEQXNNPLOMFGHSTFCNRMDFUSQREHFASDXZZOYNWNVKCRFZIDF9X9YKME9O9NJH9LFVNNSOXHSQOMBULFHBBPSGRCCGKWENQOZHRSIIHKKXAQTFISNVGIVMBDKSJYDW9VTZBAVYWWJAIYSCHGBIXKMKHBRTHWQMIWQVPWFUJQVUDZRDX9MMCXOQTQZGKECGIHATHUC9TDGKUKOYXEEBGTQYEO9KADOSMYWGQARTIUG9IUHQEBWSFHWDZCRCH9WDRJEUSQDBBGGKTOYBKYZX9LUKUGBVTEPXDOVVNSKPUWNARSILQNOQKATCUHMRVMKVHF9B9TEJDOMBDXLNKDJI9IIYRXNOQPBOVOEEGQFSZJJOFPNFVXOYZNLSOOA9FWDFJKDOQUHWHBNDWQZZVRBZJSLDVBRCGFCWXNUFTMLCHNXODSQMUIBPN9NMAXZXKUYYRUEDSLW9UEQYGSEBEOHGI9W9WAUFDEQCXVYOTBAAHFXHRGJBWGFZKIUMSWEXAD9EDALOOYQZIXKUOWJDHBHSEUDPJJRXANPPHUZWJM9KDVGJUAQHFJTWNFSULGSWMGMAOCAHTIYYJONOLKGNKRXWWZYWKITSFPQJNHQWAIJULYWPXQENPZTWZISXJBWYLENOINLFBRWWGWSWJONHIA99VGCSAT9XNMZUCSVEJMZJASUSXVUWFSVFXUIFWGIFKLEFLANHTITFCOPXRXTDXRDHLWP9RJHVQJMLPBFVHTIOQMSZECNPITTBTPLUHDQQZP9BWTWIZSOTMTZQWHCETRTKQPOHPJMJMLSBWC9ZRQAZDLAPJHAXRQZ9RUHHBPASWVUHBYX9FH9PLEHQEKCOMIHUNDVKOPKXEFM9CNP9LOLMBVHMMWNDCKHSYZEXOJAQOHMRXEGWMWFW9YVOZ9YDPHWVTKWFYUECSROYJENFPSIKHBJRSNWO9KQUENGPVULVYAQFAIYFSNIYR9LLRMYNCNQQAOPFNMWFSWSPMWNNIRNVKDZWRLGMPCBOVIMMXEZUFYPFPIGWTGOLDAEBZQADSOGVDZXHEWZGHNAAHMFPSOZD9SEPNCW9GTN9WLFDDCKMMXPXAEUUJPJFKKWMGUKVMYBH9AIEFAIIDJOAWRDKECA99XOYRSFZQKTVRJMTUAQJZUTKGXROESUYYSHTLRIZRPSNDFEEZWXCQONZYCD9TOHCBP9ISXQ9YSRZJ999Z9TETYOINSDGRBQSDTVFABHQNLTWGFYLHBHPVKLIBUMLVSURAOS9QHXDTIPKOJDLYOKRCEKCBMKVYIAKVA9WTGDWHIRUAWOVRKOSYTNIZAZNTJRFJDMNLGHTDKPKZDLBPQXRIRIVREMOBCPHMBBAUKNXHU9XIZNG9GD9LDIBBFPSI9PJNRCHXHNWAZXIACE9LUBNUWOK9LGJ9MKZQRI9CBCJUNALQKKVGGSPRJFAGCXNFO99YMLMKI9NVUZCZ9BCUEBSGMAVNKGWYWWQPZISMKAROXLQWEHOJIJOIIYRUDBNHRD9DEDQWQONAXKKSYMYCFTITZFKIXKZCGAVAFQIYEMESOIMWUUDSXJRR9RVWTAAHCOA9SCQBF9LAGPPYDXPEBKLHZ9KHKTXFP9XOVMVWIXEWMOISJHMQEXMYMZCUGEQNKGUNVRPUDPRX9IR9LBASIARWNFXXESPITSLYAQMLCLVTLHW9999999999999999999999999999999999999999999999999999FBIEUWD99A99999999C99999999DEXRPLKGBROUQMKCLMRPG9HFKCACDZ9AB9HOJQWERTYWERJNOYLW9PKLOGDUPC9DLGSUH9UHSKJOASJRU9MMRRSLICRITOROFC9FBVWLFEDNN9KJKYHUMRCJEUDGCYCWTBP9HHBEEJRFAU9FALRJWTU99NZK999999UE9VSBDVSRNTBZWPXYZPGAUTSWFLARLPXMHYBSTEUWIDOFJQJMVIACGUPTOMBWQO9AEADCFCMFJ999999WQKHJEXIHMOKQETOUTEO9JUPCDNAJQYZVXQRCXGYGEBOTMHE9HSJXVYVQUS9FPDLQWWKSYVDPCXX9LLAT

should be

WPM9JCTQH9QHBHBJCODWDNPSLFLQDZADRAEZTZDL9OEGTVRZARVLVJHZIMPBPCTAIYJKWTUSRKNNTMFOQ

instead of

UFROVDSOETBS9LAKBTYGQGECXLARNIRECGJOXZWZCPLDLSLFIGFIAOL9IRHFPBMSTEFEBE9AIKZ9RCEST

Documenting the proper way to contributing

Hi there.
After forking the repository on GitHub and cloning it locally all the go files point to the wrong package, i.e. giota, while the folder in which they reside is iota.lib.go. Could we somehow document how to contribute to the IOTA Go API? I would like to add functionality to use the lib to send MAM's to the tangle.

need to fix the test failure of the `TestNonce` method

The TestNonce method keeps fail. it will call the HasValidNonce function to do the validation. it will check if the tx hash ends with 9s I think it only works for the p27 hashes like MRYSIXABICSX9XQSLPAPQHGAPCMBDQZXH9EOHPLL9LFQNUDTETNQFUJO9DPHTNPJI9BTQH9RM9I999999.

func TestNonce(t *testing.T) {
	var trytes Trytes = "QQ9VLGQTJICJH9UZNSBXRSKBWVXCTRNGLJPEYFSZBISDCGBHGAV9TEHIMJS9LMQNHFNWVAXALKGESPWZMUMZPQCKCUFSEJZVHWZHZOEZBPTERXPHUQLQLZMENKOKAWMJ9LCFSIBSBEYCJQVQQMTMRJMDEKRXLCIRZFWQBRJYLPSK9XLWFYFTU9FBJATWPQRJBHWYJRUEXSXMBJLVWNYRTZJTHLEKDTWCGJ9OXDEZNWTKLTXXTKVFXDMRJUDAMDACRHJKZIJFJBZRVDLSTIMOWPTLLIVHCFUBMSQIPVPCSQAPZGHHNNQLWEHDTIQZQTAXJMTTROYOTIZSZKKQFXBHXFKSNAGZWHWEGXCKHSJQGBJGC9IKUSSJEAOHTPGPMIYPEXJXJKRLX9IOCUDKK9ONEUONYVGHRHXSAUZJXGVQNWSDZIYXXZMMJKRTOXSWJHBIMXPEMJTKIBSQKPICTKAQLJVOLZSGNVVBIOFJJKKJ9UBYKJWCBRPQLGBNEKEFRYCHB9PORAKEKTJZYZBFGZLONUJCPNINGUTYWTMDKTEPDASCHNVHXTUIOZ9PDALXKQYLILMUJEJWTYYAGEQXNNPLOMFGHSTFCNRMDFUSQREHFASDXZZOYNWNVKCRFZIDF9X9YKME9O9NJH9LFVNNSOXHSQOMBULFHBBPSGRCCGKWENQOZHRSIIHKKXAQTFISNVGIVMBDKSJYDW9VTZBAVYWWJAIYSCHGBIXKMKHBRTHWQMIWQVPWFUJQVUDZRDX9MMCXOQTQZGKECGIHATHUC9TDGKUKOYXEEBGTQYEO9KADOSMYWGQARTIUG9IUHQEBWSFHWDZCRCH9WDRJEUSQDBBGGKTOYBKYZX9LUKUGBVTEPXDOVVNSKPUWNARSILQNOQKATCUHMRVMKVHF9B9TEJDOMBDXLNKDJI9IIYRXNOQPBOVOEEGQFSZJJOFPNFVXOYZNLSOOA9FWDFJKDOQUHWHBNDWQZZVRBZJSLDVBRCGFCWXNUFTMLCHNXODSQMUIBPN9NMAXZXKUYYRUEDSLW9UEQYGSEBEOHGI9W9WAUFDEQCXVYOTBAAHFXHRGJBWGFZKIUMSWEXAD9EDALOOYQZIXKUOWJDHBHSEUDPJJRXANPPHUZWJM9KDVGJUAQHFJTWNFSULGSWMGMAOCAHTIYYJONOLKGNKRXWWZYWKITSFPQJNHQWAIJULYWPXQENPZTWZISXJBWYLENOINLFBRWWGWSWJONHIA99VGCSAT9XNMZUCSVEJMZJASUSXVUWFSVFXUIFWGIFKLEFLANHTITFCOPXRXTDXRDHLWP9RJHVQJMLPBFVHTIOQMSZECNPITTBTPLUHDQQZP9BWTWIZSOTMTZQWHCETRTKQPOHPJMJMLSBWC9ZRQAZDLAPJHAXRQZ9RUHHBPASWVUHBYX9FH9PLEHQEKCOMIHUNDVKOPKXEFM9CNP9LOLMBVHMMWNDCKHSYZEXOJAQOHMRXEGWMWFW9YVOZ9YDPHWVTKWFYUECSROYJENFPSIKHBJRSNWO9KQUENGPVULVYAQFAIYFSNIYR9LLRMYNCNQQAOPFNMWFSWSPMWNNIRNVKDZWRLGMPCBOVIMMXEZUFYPFPIGWTGOLDAEBZQADSOGVDZXHEWZGHNAAHMFPSOZD9SEPNCW9GTN9WLFDDCKMMXPXAEUUJPJFKKWMGUKVMYBH9AIEFAIIDJOAWRDKECA99XOYRSFZQKTVRJMTUAQJZUTKGXROESUYYSHTLRIZRPSNDFEEZWXCQONZYCD9TOHCBP9ISXQ9YSRZJ999Z9TETYOINSDGRBQSDTVFABHQNLTWGFYLHBHPVKLIBUMLVSURAOS9QHXDTIPKOJDLYOKRCEKCBMKVYIAKVA9WTGDWHIRUAWOVRKOSYTNIZAZNTJRFJDMNLGHTDKPKZDLBPQXRIRIVREMOBCPHMBBAUKNXHU9XIZNG9GD9LDIBBFPSI9PJNRCHXHNWAZXIACE9LUBNUWOK9LGJ9MKZQRI9CBCJUNALQKKVGGSPRJFAGCXNFO99YMLMKI9NVUZCZ9BCUEBSGMAVNKGWYWWQPZISMKAROXLQWEHOJIJOIIYRUDBNHRD9DEDQWQONAXKKSYMYCFTITZFKIXKZCGAVAFQIYEMESOIMWUUDSXJRR9RVWTAAHCOA9SCQBF9LAGPPYDXPEBKLHZ9KHKTXFP9XOVMVWIXEWMOISJHMQEXMYMZCUGEQNKGUNVRPUDPRX9IR9LBASIARWNFXXESPITSLYAQMLCLVTLHW9999999999999999999999999999999999999999999999999999FBIEUWD99A99999999C99999999DEXRPLKGBROUQMKCLMRPG9HFKCACDZ9AB9HOJQWERTYWERJNOYLW9PKLOGDUPC9DLGSUH9UHSKJOASJRU9MMRRSLICRITOROFC9FBVWLFEDNN9KJKYHUMRCJEUDGCYCWTBP9HHBEEJRFAU9FALRJWTU99NZK999999UE9VSBDVSRNTBZWPXYZPGAUTSWFLARLPXMHYBSTEUWIDOFJQJMVIACGUPTOMBWQO9AEADCFCMFJ999999WQKHJEXIHMOKQETOUTEO9JUPCDNAJQYZVXQRCXGYGEBOTMHE9HSJXVYVQUS9FPDLQWWKSYVDPCXX9LLAT"
	tx, err := NewTransaction(trytes)
	if err != nil {
		t.Fatal(err)
	}
	if !tx.HasValidNonce(18) {
		t.Error("cannot validate nonce")
	}
}

I don't understand the validation logic in the HasValidNonce function , looks nothing relate to the nonce, but only care about if the tx hash ends with 9

//HasValidNonce checks t's hash has valid MinWeightMagnitude.
func (t *Transaction) HasValidNonce(mwm int64) bool {
	h := t.Hash()
	for i := len(h) - 1; i > len(h)-1-int(mwm)/3; i-- {
		if h[i] != '9' {
			return false
		}
	}
	return true
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.