diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..28a804d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..804d8bd
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/monoblock.iml b/.idea/monoblock.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/monoblock.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chain/block.go b/chain/block.go
new file mode 100644
index 0000000..6f83730
--- /dev/null
+++ b/chain/block.go
@@ -0,0 +1,79 @@
+package chain
+
+import (
+ "bytes"
+ "encoding/gob"
+ "fmt"
+ "golang.org/x/crypto/sha3"
+ "log"
+ "math/rand"
+)
+
+type block struct {
+ Transactions []transaction
+ HashPrevious []byte
+ Nonce []byte
+}
+
+func NewBlock(hashPrevious []byte) block {
+ return block{
+ Transactions: nil,
+ HashPrevious: hashPrevious,
+ }
+}
+
+func (b *block) AddTransaction(t transaction) {
+ b.Transactions = append(b.Transactions, t)
+}
+
+func (b block) GenerateHash(difficulty int) []byte {
+ found := false
+ var compBytes []byte
+ for i := 0; i < difficulty; i++ {
+ compBytes = append(compBytes, []byte("0x00")...)
+ }
+ for !found {
+ random := make([]byte, 64)
+ rand.Read(random)
+ b.Nonce = random
+ var buf bytes.Buffer
+ err := gob.NewEncoder(&buf).Encode(b.Nonce)
+ if err != nil {
+ log.Fatal(err)
+ }
+ hasher := sha3.New512()
+ hasher.Write(b.ToBytes())
+ hash := hasher.Sum(nil)
+ fmt.Printf("\033[2K\r%x\n", hash)
+ if checkAllZero(XorSlice(hash[:difficulty], compBytes)) {
+ return hash
+ }
+ }
+ return nil
+}
+
+func (b block) ToBytes() []byte {
+ var bytes []byte
+ for i := 0; i < len(b.Transactions); i++ {
+ bytes = append(bytes, b.Transactions[i].ToBytes()...)
+ }
+ bytes = append(bytes, b.Nonce...)
+ return bytes
+}
+
+func XorSlice(a []byte, b []byte) []byte {
+ for i, _ := range a {
+ a[i] = a[i] ^ b[i]
+ }
+ return a
+}
+
+func checkAllZero(a []byte) bool {
+ fmt.Printf("Checking if all zero: %x\n", a)
+ for i, _ := range a {
+ if a[i] != 0x00 {
+ return false
+ }
+ }
+ return true
+}
diff --git a/chain/chain.go b/chain/chain.go
new file mode 100644
index 0000000..fef1d20
--- /dev/null
+++ b/chain/chain.go
@@ -0,0 +1 @@
+package chain
diff --git a/chain/transaction.go b/chain/transaction.go
new file mode 100644
index 0000000..1f8ac52
--- /dev/null
+++ b/chain/transaction.go
@@ -0,0 +1,43 @@
+package chain
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha256"
+ "encoding/gob"
+ "time"
+)
+
+type transaction struct {
+ Src string
+ Dst string
+ Amount int
+ Timestamp time.Time
+}
+
+func NewTransaction(source string, dst string, amount int) transaction {
+ return transaction{Src: source, Dst: dst, Amount: amount, Timestamp: time.Now()}
+}
+
+func (ta transaction) SignTransaction(privKey *rsa.PrivateKey, d int) ([]byte, error) {
+
+ return rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, ta.HashTransaction())
+}
+
+func (ta transaction) HashTransaction() []byte {
+ var buf bytes.Buffer
+ gob.NewEncoder(&buf).Encode(ta)
+ hash := sha256.New().Sum(buf.Bytes())
+ return hash
+}
+
+func (ta transaction) ToBytes() []byte {
+ bytes := []byte(ta.Src)
+ bytes = append(bytes, []byte(ta.Dst)...)
+ //fmt.Printf("%s", ta.Dst)
+ bytes = append(bytes, byte(ta.Amount))
+ bytes = append(bytes, []byte(ta.Timestamp.String())...)
+ return bytes
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..4ea6608
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module monoblock
+
+go 1.14
+
+require golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..a5090e1
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,10 @@
+golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
+golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/go_build_monoblock.exe b/go_build_monoblock.exe
new file mode 100644
index 0000000..752b197
Binary files /dev/null and b/go_build_monoblock.exe differ
diff --git a/keymgmt/keymgmt.go b/keymgmt/keymgmt.go
new file mode 100644
index 0000000..3ce54e2
--- /dev/null
+++ b/keymgmt/keymgmt.go
@@ -0,0 +1,34 @@
+package keymgmt
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "encoding/base64"
+ "golang.org/x/crypto/sha3"
+ "log"
+ "math/big"
+)
+
+type Address struct {
+ pubkey int
+ privkey *rsa.PrivateKey
+ mod *big.Int
+}
+
+func GenerateAddress() *Address {
+ key, err := rsa.GenerateKey(rand.Reader, 1024)
+
+ if err != nil {
+ log.Fatal(err)
+ }
+ newAddress := Address{pubkey: key.E, privkey: key, mod: key.N}
+ return &newAddress
+}
+
+func (a Address) GetAddress() string {
+ hasher := sha3.New224()
+ hash := hasher.Sum(a.privkey.N.Bytes())
+ b64 := "!MBPA#" + base64.StdEncoding.EncodeToString(hash)[:64]
+
+ return b64
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..ac43c4a
--- /dev/null
+++ b/main.go
@@ -0,0 +1,40 @@
+package main
+
+import (
+ "bufio"
+ "encoding/hex"
+ "fmt"
+ "monoblock/chain"
+ "monoblock/keymgmt"
+ "os"
+)
+
+const AMOUNT int = 100
+
+func main() {
+ by1, _ := hex.DecodeString("0001020304")
+ by2, _ := hex.DecodeString("0001020304")
+
+ fmt.Printf("%x", chain.XorSlice(by1, by2))
+
+ addr1 := keymgmt.GenerateAddress()
+ addr2 := keymgmt.GenerateAddress()
+ addr3 := keymgmt.GenerateAddress()
+ addr4 := keymgmt.GenerateAddress()
+ ta1 := chain.NewTransaction(addr3.GetAddress(), addr1.GetAddress(), 100)
+ ta2 := chain.NewTransaction(addr2.GetAddress(), addr4.GetAddress(), 100)
+ b1 := chain.NewBlock(nil)
+ b1.AddTransaction(ta1)
+ b1.AddTransaction(ta2)
+ hash := b1.GenerateHash(4)
+ fmt.Printf("Hash found:\n\n%x\n\n", hash)
+ bufio.NewReader(os.Stdin).ReadBytes('\n')
+}
+
+func generateKey(ch chan *keymgmt.Address, amount int) {
+ for i := 0; i < amount; i++ {
+ addr := keymgmt.GenerateAddress()
+ ch <- addr
+ }
+
+}