// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleToken {
string public name = "SimpleToken";
string public symbol = "SIM";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(uint256 _initialSupply) {
totalSupply = _initialSupply * 10 ** uint256(decimals);
balanceOf[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
}
function transfer(address _to, uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value, "Insufficient balance");
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(balanceOf[_from] >= _value, "Insufficient balance");
require(allowance[_from][msg.sender] >= _value, "Allowance exceeded");
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use sha2::{Sha256, Digest};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Block {
pub index: u64,
pub timestamp: u64,
pub transactions: Vec,
pub proof: u64,
pub previous_hash: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Transaction {
pub sender: String,
pub recipient: String,
pub amount: f64,
}
pub struct Blockchain {
pub chain: Vec,
pub current_transactions: Vec,
pub nodes: HashSet,
}
impl Blockchain {
pub fn new() -> Self {
let mut blockchain = Blockchain {
chain: Vec::new(),
current_transactions: Vec::new(),
nodes: HashSet::new(),
};
blockchain.new_block(100, "1".to_string());
blockchain
}
pub fn new_block(&mut self, proof: u64, previous_hash: String) -> Block {
let block = Block {
index: (self.chain.len() + 1) as u64,
timestamp: Utc::now().timestamp() as u64,
transactions: self.current_transactions.clone(),
proof,
previous_hash,
};
self.current_transactions.clear();
self.chain.push(block.clone());
block
}
pub fn new_transaction(&mut self, sender: String, recipient: String, amount: f64) -> usize {
self.current_transactions.push(Transaction {
sender,
recipient,
amount,
});
self.chain.last().unwrap().index + 1
}
pub fn hash(block: &Block) -> String {
let block_string = serde_json::to_string(block).unwrap();
let mut hasher = Sha256::new();
hasher.update(block_string);
format!("{:x}", hasher.finalize())
}
pub fn proof_of_work(&self, last_proof: u64) -> u64 {
let mut proof = 0;
while !self.valid_proof(last_proof, proof) {
proof += 1;
}
proof
}
fn valid_proof(&self, last_proof: u64, proof: u64) -> bool {
let guess = format!("{}{}", last_proof, proof);
let guess_hash = format!("{:x}", Sha256::digest(guess.as_bytes()));
guess_hash[..4] == "0000".to_string()
}
}