Coder Social home page Coder Social logo

blockchain-tutorial's Introduction

Code your own blockchain in less than 200 lines of Go!

Tutorial

Read our blog post first to see a walkthrough of the code.

Check out our follow-up tutorials:

Deployment steps:

  • git clone https://github.com/mycoralhealth/blockchain-tutorial.git
  • navigate to this directory and rename the example file mv example.env .env
  • go run main.go
  • open a web browser and visit http://localhost:8080/
  • to write new blocks, send a POST request (I like to use Postman) to http://localhost:8080/ with a JSON payload with BPM as the key and an integer as the value. For example:
{"BPM":50}
  • Send as many requests as you like and refresh your browser to see your blocks grow! Use your actual heart rate (Beats Per Minute) to track it over time.

Screenshot

screen

blockchain-tutorial's People

Contributors

kveselkov avatar lon-io avatar nosequeldeebee avatar tamerh 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  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

blockchain-tutorial's Issues

Probable race condition when generating a new block (#4 is still unresolved)

In reference to #4 the following block of code does not do the work intended of preventing the race condition as another thread/goroutine that is waiting to enter the critical region still addresses the old Blockchain (prevBlock := Blockchain[len(Blockchain)-1] ) . This could result in 2 blocks having the same index and prevHash

        prevBlock := Blockchain[len(Blockchain)-1] 
        mutex.Lock()
	newBlock := generateBlock(prevBlock, msg.BPM)
	mutex.Unlock()

	if isBlockValid(newBlock, prevBlock) {
		Blockchain = append(Blockchain, newBlock)
		spew.Dump(Blockchain)
	}

Condition in replaceChain is always true

  • Line 89 newBlockchain := append(Blockchain, newBlock) appending new block to blockchain
  • Line 138 if len(newBlocks) > len(Blockchain) { checking if size of new chain is bigger.

len(newBlocks) is always equals to len(Blockchain) + 1.

Several Issues running code through visual studio

Hi,

I just tried to run the whole Blockchain code in Visual Studio, and I have had a host of issues.

It would be good if someone could help me understand holistically what is going wrong?

i.e you cannot import "internal/cpu"

This in turn has created problems throughout the code.

gx issue

cannot use priv (type "github.com/libp2p/go-libp2p-crypto".PrivKey) as type "gx/ipfs/QmTW4SdgBWq9GjsBsHeUx8WuGxzhgzAf88UMH2w62PC8yK/go-libp2p-crypto".PrivKey in argument to libp2p.Identity:
"github.com/libp2p/go-libp2p-crypto".PrivKey does not implement "gx/ipfs/QmTW4SdgBWq9GjsBsHeUx8WuGxzhgzAf88UMH2w62PC8yK/go-libp2p-crypto".PrivKey (wrong type for Equals method)
have Equals("github.com/libp2p/go-libp2p-crypto".Key) bool
want Equals("gx/ipfs/QmTW4SdgBWq9GjsBsHeUx8WuGxzhgzAf88UMH2w62PC8yK/go-libp2p-crypto".Key) bool
./main.go:88:9: cannot use i (type "gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr".Multiaddr) as type "github.com/multiformats/go-multiaddr".Multiaddr in assignment:
"gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr".Multiaddr does not implement "github.com/multiformats/go-multiaddr".Multiaddr (wrong type for Decapsulate method)
have Decapsulate("gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr".Multiaddr) "gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr".Multiaddr
want Decapsulate("github.com/multiformats/go-multiaddr".Multiaddr) "github.com/multiformats/go-multiaddr".Multiaddr
./main.go:100:2: cannot use basicHost (type "gx/ipfs/QmYrWiWM4qtrnCeT3R14jY3ZZyirDNJgwK57q4qFYePgbd/go-libp2p-host".Host) as type "github.com/libp2p/go-libp2p-host".Host in return argument:
"gx/ipfs/QmYrWiWM4qtrnCeT3R14jY3ZZyirDNJgwK57q4qFYePgbd/go-libp2p-host".Host does not implement "github.com/libp2p/go-libp2p-host".Host (wrong type for Addrs method)
have Addrs() []"gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr".Multiaddr
want Addrs() []"github.com/multiformats/go-multiaddr".Multiaddr

Issue with imports in main.go

While running the application in my system, I found issues with main.go with one package(str).

I would like to create one PR for that.

Please approve.

provide hash in genesis block

reader comment:

Question: is it intentional for the first two blocks (indexes 0 and 1) to both have the previous hash equal to “”? I would think we’d want to call genesisBlock.Hash = calculateHash(genesisBlock) in main() right after creating the initial struct, so that the subsequent blocks would have an actual PrevHash value.

undefined: libp2p.NoEncryption error prevents application to compile and run

From blog post:

https://medium.com/coinmonks/code-a-simple-p2p-blockchain-in-go-46662601f417

If not commented out, this line breaks compilation of the sample program:

https://github.com/mycoralhealth/blockchain-tutorial/blob/master/p2p/main.go#L74

linter declares undefined libp2p.NoEncryption

Trying to run it results in:

$ go run main.go -l 10000 -secio
# command-line-arguments
./main.go:75:23: undefined: libp2p.NoEncryption

Commenting it out allows the program to run as expected.

set json header

reader comment:

add:
w.Header().Set(“Content-Type”, “application/json”)

to your handlers and respondWithJson functions so that it actually returns as a JSON content-type in calls, but that is just a minor detail.

how can I do the same thing but on different machines rather than localhost?

Hello,
I am trying to making a p2p blockchain and this code was extremely helpful but it has just one problem that the blockchain is using 127.0.0.1: port as the usual address. I cannot use another machine to connect to this port because it is broadcasting on localhost. Any idea how to modify code to broadcast it as *: port. That way any machine could be used to connect in this p2p network.

libp2p no longer supports gx

From go-libp2p readme:

Before adopting gomod, libp2p used gx to manage dependencies using IPFS.

Due to the difficulties in keeping both dependency management solutions up-to-date, gx support was ended in April 2019.

It it possible to build any example from this repository with new versions of libp2p?

When trying to run p2p blockchain example:

# github.com/libp2p/go-libp2p-loggables
../../../../go/src/github.com/libp2p/go-libp2p-loggables/loggables.go:19:26: undefined: log.Loggable
../../../../go/src/github.com/libp2p/go-libp2p-loggables/loggables.go:20:9: undefined: log.Metadata
../../../../go/src/github.com/libp2p/go-libp2p-loggables/loggables.go:27:21: undefined: log.Loggable
../../../../go/src/github.com/libp2p/go-libp2p-loggables/loggables.go:28:9: undefined: log.Metadata
../../../../go/src/github.com/libp2p/go-libp2p-loggables/loggables.go:33:23: undefined: log.Metadata
../../../../go/src/github.com/libp2p/go-libp2p-loggables/loggables.go:38:9: undefined: log.Metadata
# github.com/libp2p/go-addr-util
../../../../go/src/github.com/libp2p/go-addr-util/addr.go:101:5: log.Event undefined (type *log.ZapEventLogger has no field or method Event)
../../../../go/src/github.com/libp2p/go-addr-util/addr.go:101:63: undefined: log.Loggable
../../../../go/src/github.com/libp2p/go-addr-util/addr.go:106:10: undefined: log.Metadata
# github.com/libp2p/go-libp2p-secio
../../../../go/src/github.com/libp2p/go-libp2p-secio/protocol.go:117:11: log.EventBegin undefined (type *log.ZapEventLogger has no field or method EventBegin)
# github.com/libp2p/go-libp2p/p2p/protocol/identify
../../../../go/src/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go:367:6: log.Event undefined (type *log.ZapEventLogger has no field or method Event)
../../../../go/src/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go:367:67: undefined: log.Metadata

use strConv instead of string()

string() will most likely be deprecated in Go 2.0. Using strConv instead in the following

func calculateHash(block Block) string {
	record := string(block.Index) + block.Timestamp + string(block.BPM) + block.PrevHash

may generate blocks with same Index?

newBlock, err := genearteBlock(BlockChain[len(BlockChain)-1], bpm)
while in high concurrency, blocks with same Index may be generated?
for example, here is the result in my test

{
"Index": 422,
"TimeStamp": "2018-01-30 13:58:54.183422 +0800 CST m=+753.675702708",
"BPM": 354,
"Hash": "224afd49a6cc91b53981401212c9ef77065d10622c65799468c2f7d13a8ba98d",
"PrevHash": "780bebe0c96726d58d7ade6a64f1f6ae79354e069d63f842c7bd759b843360ed"
},
{
"Index": 423,
"TimeStamp": "2018-01-30 13:58:54.31362 +0800 CST m=+753.805901260",
"BPM": 355,
"Hash": "928ddf91e2095e7e5f892f91fd4f7f77d291c2bfac4e402f1ed6c05e50e7c4ee",
"PrevHash": "224afd49a6cc91b53981401212c9ef77065d10622c65799468c2f7d13a8ba98d"
},
{
"Index": 423,
"TimeStamp": "2018-01-30 13:58:54.31362 +0800 CST m=+753.805901306",
"BPM": 71,
"Hash": "57aa47f8997bf9197a3e77beae0b79476f9f64b3d8e1d59398c8322941bc1b35",
"PrevHash": "224afd49a6cc91b53981401212c9ef77065d10622c65799468c2f7d13a8ba98d"
}

maximum capacity

is there a way to set a maximum capacity on the number of blockchains, when the first block generated ? so that if anyone change that value, hash value will not match

Error

I'm getting this Error, could someone help?

go run p2pblock.go -l 10000 -secio                                                                                                                                                           
# command-line-arguments
./p2pblock.go:218:21: cannot use logging.INFO (type logging.Level) as type "github.com/ipfs/go-log/v2".LogLevel in argument to "github.com/ipfs/go-log/v2".SetAllLoggers

windows line ending bug

as title:
when I input 70.
it shows a 70\r cause by \r\n line ending in windows.

2018/11/08 15:42:57 listening for connections
2018/11/08 15:44:18 Got a new stream!
> 70
2018/11/08 15:47:32 strconv.Atoi: parsing "**70\r**": invalid syntax

dial failed

Failed to dial through 0 known relay hosts

2018/10/23 20:41:17 I am /p2p-circuit/ipfs/QmVEiBiyRV1ntWNTHimziDHzFu41LDqV9GaxbYztavXSVj
2018/10/23 20:41:17 Now run "go run main.go -l 10002 -d /p2p-circuit/ipfs/QmVEiBiyRV1ntWNTHimziDHzFu41LDqV9GaxbYztavXSVj -secio" on a different terminal
2018/10/23 20:41:17 opening stream
20:41:17.070 INFO swarm2: got error on dial to /p2p-circuit: <peer.ID QmavXSVj> --> <peer.ID QmEMYDLm> dial attempt failed: Failed to dial through 0 known relay hosts swarm_dial.go:382
2018/10/23 20:41:17 dial attempt failed: <peer.ID QmavXSVj> --> <peer.ID QmEMYDLm> dial attempt failed: Failed to dial through 0 known relay hosts

another problem in windows10 terminal

when print "70",in windows terminal ,you well see"strconv.Atoi:"70/r" invalid sy
the renson is windows system "Enter" key is"/r" in end.
so change you code in 179 line like this:
sendData = strings.Replace(sendData, "\r", "", -1)

POST doesnt work

Hello I tried to run it on Windows (go build)
and got it run successfully on my localhost, but I can not send POST requests.

This is how it looks in the terminal:

blockchain-tutorial.exe
(2019/03/26 02:51:36 HTTP Server Listening on port : 8080
main.Block) {
 Index: (int) 0,
 Timestamp: (string) (len=52) "2019-03-26 02:51:36.2204679 +0100 CET m=+0.007995401",
 BPM: (int) 0,
 Hash: (string) (len=64) "f1534392279bddbf9d43dde8701cb5be14b82f76ec6607bf8d6ad557f60f304e",
 PrevHash: (string) ""
}

This is what I try to send with CURL with POST request as mentioned in the README

C:\Windows\System32>curl --request POST --data '{"BPM":50}' http://localhost:8080 -v
Note: Unnecessary use of -X or --request, POST is already inferred.
* Rebuilt URL to: http://localhost:8080/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.55.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 10 out of 10 bytes
< HTTP/1.1 400 Bad Request
< Content-Type: application/json
< Date: Tue, 26 Mar 2019 01:56:33 GMT
< Content-Length: 2
<
{}* Connection #0 to host localhost left intact

But there is no block added, so what cause the issue?
I tried even another port, but still the issue exist.

Hope you can help, Thanks

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.