Skip to content

Commit

Permalink
deposit from web and async every once after deposit
Browse files Browse the repository at this point in the history
  • Loading branch information
youwenbusi committed Aug 3, 2020
1 parent 62ffd65 commit cf3a3f5
Show file tree
Hide file tree
Showing 108 changed files with 179 additions and 8,359 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
39 changes: 38 additions & 1 deletion zeth/merkle_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

from __future__ import annotations
from zeth.mimc import MiMC7
from os.path import exists
from os.path import exists, dirname, abspath
import json
import math
from typing import Dict, List, Tuple, Iterator, cast, Any

import sys
sys.path.append('../zkservice/zkserver')
#sys.path.append('./zkservice/zkserver')
from zkserverapp.models import merkletree

ZERO_ENTRY = bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000000")
Expand Down Expand Up @@ -223,6 +227,39 @@ def save(self) -> None:
with open(self.filename, "w") as tree_f:
json.dump(self.tree_data.to_json_dict(), tree_f)

class sqlMerkleTree(MerkleTree):
"""
Version of MerkleTree that load the MerkleTree data from mysql.
"""
def __init__(
self, tree_data: MerkleTreeData, depth: int):
MerkleTree.__init__(self, tree_data, depth)

def open(max_num_leaves: int) -> sqlMerkleTree:
depth = int(math.log(max_num_leaves, 2))
if merkletree.objects.all().count() == 0:
tree_data = MerkleTreeData.empty_with_depth(depth)
else:
result = merkletree.objects.all().last()
print("mysql search result: ", result)
json_dict = json.loads(result.tree_data)
tree_data = MerkleTreeData.from_json_dict(json_dict)
assert depth == tree_data.depth
return sqlMerkleTree(tree_data, depth)

def save(self) -> None:
if merkletree.objects.all().count() == 0:
json_str = json.dumps(self.tree_data.to_json_dict())
print("json_str: ", json_str)
merkletree.objects.create(tree_data = json_str, is_new = True)
else:
result = merkletree.objects.all().last()
print("mysql search result: ", result)
json_str = json.dumps(self.tree_data.to_json_dict())
result.tree_data = json_str
result.is_new = True
result.save()


def _leaf_address_to_node_address(address_leaf: int, tree_depth: int) -> int:
"""
Expand Down
5 changes: 2 additions & 3 deletions zeth/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
receive_note, compute_nullifier, compute_commitment
from zeth.constants import ZETH_MERKLE_TREE_DEPTH
from zeth.contracts import MixOutputEvents
from zeth.merkle_tree import PersistentMerkleTree
from zeth.merkle_tree import sqlMerkleTree
from zeth.utils import EtherValue, short_commitment, from_zeth_units
from api.zeth_messages_pb2 import ZethNote
from os.path import join, basename, exists
Expand Down Expand Up @@ -133,8 +133,7 @@ def __init__(
self.state_file = join(wallet_dir, f"state_{username}")
self.state = _load_state_or_default(self.state_file)
_ensure_dir(join(self.wallet_dir, SPENT_SUBDIRECTORY))
self.merkle_tree = PersistentMerkleTree.open(
join(wallet_dir, MERKLE_TREE_FILE),
self.merkle_tree = sqlMerkleTree.open(
int(math.pow(2, ZETH_MERKLE_TREE_DEPTH)))
self.merkle_tree_changed = False
self.next_addr = self.merkle_tree.get_num_entries()
Expand Down
19 changes: 12 additions & 7 deletions zkclient/settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Django settings for zkclient project.
Django settings for zkserver project.
Generated by 'django-admin startproject' using Django 3.0.8.
Expand All @@ -20,7 +20,7 @@
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'yg!x=us*u&ja2*rfqz38v96nr$z(-^=c-&%)gvj+vaxq*csw6f'
SECRET_KEY = 'zt9&h=+9^j@!%jc^5pv==$fe&^ak7+2c0d$6k4!ao9ck4(ydc7'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
Expand All @@ -37,6 +37,7 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'zkserverapp'
]

MIDDLEWARE = [
Expand All @@ -49,12 +50,12 @@
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'zkclient.urls'
ROOT_URLCONF = 'zkserver.urls'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand All @@ -67,16 +68,20 @@
},
]

WSGI_APPLICATION = 'zkclient.wsgi.application'
WSGI_APPLICATION = 'zkserver.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'merkletree',
'USER': 'root',
'PASSWORD': '8614',
'HOST':'127.0.0.1',
'PORT':'3306',
}
}

Expand Down
2 changes: 2 additions & 0 deletions zkclientapp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import pymysql
pymysql.install_as_MySQLdb()
5 changes: 2 additions & 3 deletions zkclientapp/admin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from django.contrib import admin

# Register your models here.
from .models import merkletree

# Register your models here.


admin.site.register(merkletree)
admin.site.register(merkletree)

3 changes: 2 additions & 1 deletion zkclientapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ class merkletree(models.Model):
class Meta:
db_table = 'merkletree'
mid = models.AutoField(max_length=11,db_column='MID',primary_key=True)
tree_data = models.TextField(max_length=40000, db_column='tree_data', blank=False)
tree_data = models.TextField(max_length=40000, db_column='tree_data', blank=False)
is_new = models.BooleanField(db_column='is_new', default=False, blank=False)
121 changes: 113 additions & 8 deletions zkclientapp/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@
from commands.event_sync import event_sync
from commands.zeth_deposit import deposit
from commands.zeth_token_approve import token_approve
from commands.zeth_token_deploy import deploy_token
from commands.zeth_deploy import deploy
from commands.zeth_mix import mix
from commands.zeth_ls_commits import ls_commits
from commands.zeth_ls_notes import ls_notes
from commands.zeth_deploy import deploy
from commands.utils import load_zeth_address, load_zeth_address_secret, open_wallet
from zeth.utils import EtherValue
from python_web3.eth_account.account import Account
from commands.constants import USER_DIR, FISCO_ADDRESS_FILE, WALLET_DIR_DEFAULT
from commands.constants import USER_DIR, FISCO_ADDRESS_FILE, WALLET_DIR_DEFAULT, ADDRESS_FILE_DEFAULT
from django.shortcuts import render
import json
import time
from django.http import JsonResponse
from os.path import exists
from . import models

'''
The wallet of user is designed as that every wallet need to be specified a username and store the
Expand All @@ -27,10 +34,17 @@
def genFiscoAddr(request) -> None:
result = {}
req = json.loads(request.body)
keystore_file = "{}/{}/{}".format(USER_DIR, req['username'], FISCO_ADDRESS_FILE)
if exists(keystore_file):
result['status'] = 1
result['text'] = 'keystore existed'
return JsonResponse(result)
(address, publickey) = gen_fisco_address(req['username'], req['password'])
result['status'] = 0
result['address'] = address
result['publickey'] = publickey
JsonResponse(result)
pubkey = ''.join(['%02X' % b for b in publickey])
result['publickey'] = "0x" + pubkey.lower()
return JsonResponse(result)

'''
make wallet by import the Fisco account that the user want to use with privatekey, username and password
Expand All @@ -41,7 +55,9 @@ def importFiscoAddr(request) -> None:
account = Account.privateKeyToAccount(req['privatekey'])
keystore_file = "{}/{}/{}".format(USER_DIR, req['username'], FISCO_ADDRESS_FILE)
if exists(keystore_file):
raise ClickException(f"ZethAddress file {keystore_file} exists")
result['status'] = 1
result['text'] = 'keystore existed'
return JsonResponse(result)
user_dir = "{}/{}/{}".format(USER_DIR, req['username'], WALLET_DIR_DEFAULT)
_ensure_dir(user_dir)
keytext = Account.encrypt(account.privateKey, req['password'])
Expand All @@ -50,9 +66,11 @@ def importFiscoAddr(request) -> None:
print(f"{req['username']}'s address: {account.address}")
print(f"{req['username']}'s publickey: {account.publickey}")
print(f"fisco account keypair written to {keystore_file}")
result['status'] = 0
result['address'] = account.address
result['publickey'] = account.publickey
JsonResponse(result)
pubkey = ''.join(['%02X' % b for b in account.publickey])
result['publickey'] = "0x" + pubkey.lower()
return JsonResponse(result)


'''
Expand All @@ -61,6 +79,93 @@ def importFiscoAddr(request) -> None:
def genZbacAddr(request) -> None:
result = {}
req = json.loads(request.body)
addr_file = "{}/{}/{}".format(USER_DIR, req['username'], ADDRESS_FILE_DEFAULT)
if exists(addr_file):
result['status'] = 1
result['text'] = 'account existed'
return JsonResponse(result)
zbac_addr = gen_address(req['username'])
result['address'] = zbac_addr
JsonResponse(result)
result['status'] = 0
result['address'] = str(zbac_addr)
return JsonResponse(result)

'''
deploy bac contract, only used by admin
'''
def deployToken(request) -> None:
result = {}
req = json.loads(request.body)
token_address = deploy_token(req['miner_address'], req['token_amount'])
if token_address :
result['status'] = 0
result['address'] = str(token_address)
return JsonResponse(result)
result['status'] = 1
result['text'] = 'deploy bac contract failed'
return JsonResponse(result)

'''
deploy zksnark mixer contract, only used by admin
'''
def deployMixer(request) -> None:
result = {}
req = json.loads(request.body)
mixer_address = deploy(req['token_address'])
if mixer_address :
result['status'] = 0
result['address'] = str(mixer_address)
return JsonResponse(result)
result['status'] = 1
result['text'] = 'deploy zksnark mixer contract failed'
return JsonResponse(result)

'''
deposit bac to mixer and get two notes with specified value
'''
def depositBac(request) -> None:
#todo: 从数据库中获取前一个交易是否已经完成,也就是merkletree是否已经更新
#即is_new是否为True,如果不是则等待,如果是则置为False,开始执行交易
while (models.merkletree.objects.all().count() and not models.merkletree.objects.all().last().is_new):
time.sleep(1)
sqlResult = models.merkletree.objects.all().last()
if models.merkletree.objects.all().count():
sqlResult.is_new = False
sqlResult.save()
result = {}
req = json.loads(request.body)
keystore_file = "{}/{}/{}".format(USER_DIR, req['username'], FISCO_ADDRESS_FILE)
addr_file = "{}/{}/{}".format(USER_DIR, req['username'], ADDRESS_FILE_DEFAULT)
if exists(keystore_file) and exists(addr_file) :
outputapprove = token_approve(req['token_amount'], req['mixer_address'], req['token_address'], req['username'], req['password'])
if outputapprove :
zeth_address = load_zeth_address(req['username'])
output_specs = []
print(str(zeth_address.addr_pk) + ',' + str(req['value1']))
output_specs.append(str(zeth_address.addr_pk) + ',' + str(req['value1']))
output_specs.append(str(zeth_address.addr_pk) + ',' + str(req['value2']))
outputdeposit = deposit(req['mixer_address'], req['username'], req['password'], req['token_amount'], output_specs)
if outputdeposit :
event_sync(req['mixer_address'])
js_secret = load_zeth_address_secret(req['username'])
wallet = open_wallet(None, js_secret, req['username'])
total = EtherValue(0)
commits = []
for addr, short_commit, value in wallet.note_summaries():
total = total + value
commits.append(short_commit)
result['status'] = 0
result['commits'] = commits
result['total_value'] = total.ether()
return JsonResponse(result)
else:
result['status'] = 1
result['text'] = 'deposit failed'
return JsonResponse(result)
else:
result['status'] = 1
result['text'] = 'token approve failed'
return JsonResponse(result)

result['status'] = 1
result['text'] = 'your account is not recorded in server, please import it firstly or create a new one'
return JsonResponse(result)
3 changes: 3 additions & 0 deletions zkclientapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@
url(r'^post$', views.post),
url(r'^genFiscoAddr$', routes.genFiscoAddr),
url(r'^genZbacAddr$', routes.genZbacAddr),
url(r'^deployToken$', routes.deployToken),
url(r'^deployMixer$', routes.deployMixer),
url(r'^depositBac$', routes.depositBac),
]
10 changes: 5 additions & 5 deletions zkclientapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ def index(request):

"学习笔记的主页"

return render(request,'zkclientapp/template/index.html')
return render(request,'zkserverapp/template/index.html')

def get_html(request):
return render(request, 'zkclientapp/template/get.html')
return render(request, 'zkserverapp/template/get.html')

def get(request):
context = {}
# 通过request.GET['name']形式获取get表单内容
# result为重定向到的result.html所使用的变量
context['result'] = f"你搜索的内容为:{request.GET['q']}"
return render(request, 'zkclientapp/template/result.html', context)
return render(request, 'zkserverapp/template/result.html', context)

def post_html(request):
# 不能和get一样使用render_to_response必须使用render进行重定向,不然服务端不会设置csrf_token
# return render_to_response('post.html')
return render(request, 'zkclientapp/template/post.html')
return render(request, 'zkserverapp/template/post.html')

def post(request):
context = {}
# 通过request.GET['name']形式获取post表单内容
# result为重定向到的result.html所使用的变量
context['result'] = f"你搜索的内容为:{request.POST['q']}"
return render(request, 'zkclientapp/template/result.html', context)
return render(request, 'zkserverapp/template/result.html', context)
Binary file removed zkservice/zkserver/db.sqlite3
Binary file not shown.
21 changes: 0 additions & 21 deletions zkservice/zkserver/manage.py

This file was deleted.

Empty file.
Loading

0 comments on commit cf3a3f5

Please sign in to comment.